#opencvって
画像処理の定番ライブラリです。
画像処理って面白い。AR VRやりたい。
AR機能とかは確か拡張機能なんでインストール方法が別です。
一からビルドしないといけないです。しかも拡張機能ごとになんか設定違ったりめんどい。
よって今回省きます。
この辺りは結構の情報はまとまってますよ。
https://learnopencv.com/
https://www.pyimagesearch.com/
公式も良い
https://vovkos.github.io/doxyrest-showcase/opencv/sphinx_rtd_theme/page_tutorial_root.html
https://github.com/shibatch/rectdetect
https://www.youtube.com/watch?v=HpaY0HOomAI
https://www.youtube.com/watch?v=BLJEYui0XcY
動いてる状態で検出
https://shibata.naist.jp/~n-sibata/software/baum/
https://www.youtube.com/watch?v=KtO5TxG4T0M
opencv動画たち
http://miyamotok0105.hatenablog.com/entry/2017/03/12/182056
#opencvの動作環境
mac
linux
win(今回省きます。)
#opencvの言語環境
もっといろんな言語で動いてると思いますが下記に絞ります。
c言語でも書けますが、自分の場合g++コンパイラでないと通りませんでした。
ただc言語で書いてるソースを使うこと自体は可能です。
C
http://opencv.jp/opencv-2svn/c/
http://opencv.jp/opencv-2svn_org/c/
C++
http://opencv.jp/opencv-2svn/cpp/
http://opencv.jp/opencv-2svn_org/cpp/
python
http://opencv.jp/opencv-2svn/py/
http://opencv.jp/opencv-2svn_org/py/
#opencv2とopencv3で
http://tatsyblog.sakura.ne.jp/wordpress/programming/cpp/662/
この辺が変わってるようです。
cv::imread
cv::cvtColor
cv::TermCriteria
cv::VideoCapture::get
cv::PCA
#Pythonの開発環境
##Pythonインストール(mac,linux)
すごいハマルことが多かったので最短をメモ。pythonしてる人の場合はcondaで入れるのが最短です。
condaについてはここには書いていません。一からビルドする場合はちょっと時間のある時にやった方がいいです。
####condaの場合
conda install -c menpo opencv=2.4.11
or
conda install -c menpo opencv3=3.1.0
####ビルドの場合
結構時間がかかります。
git clone https://github.com/Itseez/opencv.git
cd opencv
mkdir build
cd build
cmake ..
make -j4 or make -j8
sudo make install
azureでエラッた時にオプション弄りまくった。
cmake -D WITH_OPENMP=ON -D CMAKE_BUILD_TYPE=RELEASE -D BUILD_opencv_python2=Off -D BUILD_opencv_python3=On -D PYTHON2_EXECUTABLE="" -D PYTHON2_INCLUDE_DIR="" -D PYTHON2_LIBRARY="" -D PYTHON2_PACKAGES_PATH="" -D OPENCV_FORCE_PYTHON_LIBS=On -D PYTHON3_PACKAGES_PATH=$PYTHON3_PACKAGES_PATH -D CMAKE_INSTALL_PREFIX=$LOCAL_PREFIX -D WITH_CUDA=Off -D BUILD_opencv_photo=OFF -D BUILD_opencv_shape=OFF -D BUILD_opencv_video=OFF -D ENABLE_NEON=OFF -D WITH_DC1394=ON -D WITH_FFMPEG=OFF ..
##Pythonアンインストール
うまくいかなかった時は何度か入れて消してをすることがあります。何個かバージョンが重なってる場合とか一回全部消した方がいい場合がありました。バージョンが古くなってしまってる場合もあるので気をつけてください。
####condaの場合
何個も入っちゃってた場合は全部消す
conda uninstall -c menpo opencv=2.4.11
conda uninstall opencv
conda uninstall opencv3
全部消えたかを確認
conda list | grep opencv
####ビルドの場合
sudo make uninstall
#Pythonで動かしてみる
pyenv
anaconda
python2.7
mac
##カメラキャプション
カメラ付きのパソコンの場合はいきなり自分の顔が登場します。
numpyがない場合は入れてください。
pip install numpy
# -*- coding: utf-8 -*-
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Display the resulting frame
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
#Haar-Like特徴
画像の一部を切り出し、局所的な明暗差を算出。
特徴を元にカテゴリを分類する。
アルゴリズムイメージの動画。見ればなんとなくわかる。
https://vimeo.com/12774628
xmlをgitから取得して指定してください。
https://github.com/opencv/opencv/blob/master/data/haarcascades
ファイル名 | 内容 |
---|---|
haarcascade_eye.xml | 目 |
haarcascade_eye_tree_eyeglasses.xml | 眼鏡 |
haarcascade_frontalcatface.xml | 猫の顔(正面) |
haarcascade_frontalcatface_extended.xml | 猫の顔(正面) |
haarcascade_frontalface_alt.xml | 顔(正面) |
haarcascade_frontalface_alt2.xml | 顔(正面) |
haarcascade_frontalface_alt_tree.xml | 顔(正面) |
haarcascade_frontalface_default.xml | 顔(正面) |
haarcascade_fullbody.xml | 全身 |
haarcascade_lefteye_2splits.xml | 左目 |
haarcascade_licence_plate_rus_16stages.xml | ロシアのナンバープレート(全体) |
haarcascade_lowerbody.xml | 下半身 |
haarcascade_profileface.xml | 顔(証明写真) |
haarcascade_righteye_2splits.xml | 右目 |
haarcascade_russian_plate_number.xml | ロシアのナンバープレート(数字) |
haarcascade_smile.xml | 笑顔 |
haarcascade_upperbody.xml | 上半身 |
#python2
import cv2
import sys
cascPath = sys.argv[1]
faceCascade = cv2.CascadeClassifier(cascPath)
video_capture = cv2.VideoCapture(0)
while True:
# Capture frame-by-frame
ret, frame = video_capture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags=cv2.CASCADE_SCALE_IMAGE
)
# Draw a rectangle around the faces
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
# Display the resulting frame
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()
テンプレートマッチング
2つの画像を比べて、似た画像がないか調べる。
ほぼ完全一致が求められるが、ある程度の精度は出る。
動かない場合は↓を参照。
このほかには特徴量抽出して場所を特定する方法がある。
また深層学習と組み合わせたマッチングも研究分野としては興味深い。
https://arxiv.org/pdf/1705.08593.pdf
https://ricardodeazambuja.com/deep_learning/2017/03/05/easy-peasy_conv_deep_learning_two/ https://github.com/sunsided/convolution-template-matching https://www.jstage.jst.go.jp/article/transinf/E100.D/1/E100.D_2016EDP7233/_pdf
http://cs231n.stanford.edu/reports/2017/pdfs/817.pdf
#LBP特徴
ヒストグラムにより特徴を算出。
https://pebbie.wordpress.com/2011/11/10/local-binary-pattern-in-opencv-python/
import cv
def calc_lbp(im):
"""
calculate LBP (Local Binary Pattern) image N8 neighborhood
"""
sz = cv.GetSize(im)
gr = cv.CreateImage(sz, 8, 1)
lbp = cv.CreateImage(sz, 8, 1)
#convert to grayscale
cv.CvtColor(im, gr, cv.CV_BGR2GRAY)
LBPMASK = [(0,-1),(1,-1),(1,0),(1,1),(0,1),(-1,-1),(-1,0),(-1,1)]
for y in xrange(1, sz[1]-2):
for x in xrange(1, sz[0]-2):
n = 0
gv = gr[y,x]
for i in xrange(len(LBPMASK)):
m = LBPMASK[i]
if gr[y+m[1], x+m[0]]>gv:
n += 1 << i
lbp[y,x] = n
return lbp
if __name__ == '__main__':
im = cv.LoadImage('jalan2.jpg')
lbpim = calc_lbp(im)
cv.ShowImage('lbp', lbpim)
key = cv.WaitKey(0)
import cv2
converter = cv2.HOGDescriptor()
img = cv2.imread('test.png')
hog = hog.compute(img)
#カスケード分類器を作る
##opencv_createsamples
正解画像を1つのベクトルファイルにする。正解画像は7000枚以上、不正解画像は3000枚以上あると良いと書かれてるが場合によると思われる。
http://kivantium.hateblo.jp/entry/2015/05/13/153122
https://www.pro-s.co.jp/engineerblog/opencv/post_6397.html
opencv_createsamples -info train.dat -vec train.vec -num 1000
##opencv_traincascade
Haar-Like特徴・LBP特徴・HOG特徴のいずれかで機械学習。
xmlファイルの吐き出し。あとはxmlを読み込んで使えばOK。
opencv_traincascade -data cascade/ -vec train.vec -bg bg.dat -numPos 900 -numNeg 1000 -featureType LBP -mode ALL
#動画を再生する
動画は好きな動画を探してきて、ffmpegで形式をmp4に変換してフレームを下げた。
http://qiita.com/miyamotok0105/items/6de05e5a13e7ffd456fc
# -*- coding: utf-8 -*-
import numpy as np
import cv2
cap = cv2.VideoCapture('sample.mp4')
fps = 15
size = (640,480)
cap.set(3, size[0]) # Width
cap.set(4, size[1]) # Heigh
cap.set(5, fps) # FPS
while(cap.isOpened()):
ret, frame = cap.read()
# gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
#VideoWriterを使った例
「ストリームに最新の画像フレームが一枚ずつ新たに読み込まれる」というのがOpenCVの動画読み込みの仕様。
# -*- coding: utf-8 -*-
#!/usr/bin/python
import cv2
import time
class Camera():
# Constructor...
def __init__(self):
self.cap = cv2.VideoCapture(0) # Prepare the camera...
print("Camera warming up ...")
time.sleep(1)
# if self.cap.isOpened():
# print(self.cap.get(3))
# print(self.cap.get(4))
w = int(self.cap.get(3)) # Frame width...
h = int(self.cap.get(4)) # Frame hight...
fps = 20.0 # Frames per second...
resolution = (w, h) # Frame size/resolution...
# Prepare Capture
self.ret, self.frame = self.cap.read()
# Prepare output window...
self.winName = "Motion Indicator"
cv2.namedWindow(self.winName, cv2.WINDOW_AUTOSIZE)
# Read three images first...
self.prev_frame = cv2.cvtColor(self.cap.read()[1],cv2.COLOR_RGB2GRAY)
self.current_frame = cv2.cvtColor(self.cap.read()[1],cv2.COLOR_RGB2GRAY)
self.next_frame = cv2.cvtColor(self.cap.read()[1],cv2.COLOR_RGB2GRAY)
# Define the codec and create VideoWriter object
self.fourcc = cv2.VideoWriter_fourcc(*'H264') # You also can use (*'XVID')
self.out = cv2.VideoWriter('output.avi',self.fourcc, fps, (w, h), True)
# Frame generation for Browser streaming wiht Flask...
def get_frame(self):
self.frames = open("stream.jpg", 'w+')
s, img = self.cap.read()
if s: # frame captures without errors...
cv2.imwrite("stream.jpg", img) # Save image...
return self.frames.read()
def diffImg(self, tprev, tc, tnex):
# Generate the 'difference' from the 3 captured images...
Im1 = cv2.absdiff(tnex, tc)
Im2 = cv2.absdiff(tc, tprev)
return cv2.bitwise_and(Im1, Im2)
def captureVideo(self):
# Read in a new frame...
self.ret, self.frame = self.cap.read()
# Image manipulations come here...
# This line displays the image resulting from calculating the difference between
# consecutive images...
diffe = self.diffImg(self.prev_frame, self.current_frame, self.next_frame)
cv2.imshow(self.winName,diffe)
# Put images in the right order...
self.prev_frame = self.current_frame
self.current_frame = self.next_frame
self.next_frame = cv2.cvtColor(self.frame, cv2.COLOR_RGB2GRAY)
return()
def saveVideo(self):
# Write the frame...
self.out.write(self.frame)
return()
def __del__(self):
self.cap.release()
cv2.destroyAllWindows()
self.out.release()
print("Camera disabled and all output windows closed...")
return()
def main():
# Create a camera instance...
cam1 = Camera()
while(True):
# Display the resulting frames...
cam1.captureVideo() # Live stream of video on screen...
cam1.saveVideo() # Save video to file 'output.avi'...
if cv2.waitKey(1) & 0xFF == ord('q'):
break
return()
if __name__=='__main__':
main()
#ブラウザで確認する
主にラズパイなど端末内でopencvプラスhttpサーバーを実行する場合などに下記を使用して状況を確認するサーバーを作れる。screenコマンドやtmuxコマンドを使ってバックグラウンドで動かすのが最短だが、nginxやapache上に配置してもよし。個人的にはapacheのが初心者向け。
##BaseHTTPServerとSocketServerを使った例
#!/usr/bin/python
'''
Author:
A Simple mjpg stream http server
use python2
python simple_mjeg_streamer_...py
then see down
http://127.0.0.1:8080/cam.mjpg
'''
import cv2
from PIL import Image
import threading
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
from SocketServer import ThreadingMixIn
import StringIO
import time
capture=None
class CamHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path.endswith('.mjpg'):
self.send_response(200)
self.send_header('Content-type','multipart/x-mixed-replace; boundary=--jpgboundary')
self.end_headers()
while True:
try:
rc,img = capture.read()
if not rc:
continue
imgRGB=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
jpg = Image.fromarray(imgRGB)
tmpFile = StringIO.StringIO()
jpg.save(tmpFile,'JPEG')
self.wfile.write("--jpgboundary")
self.send_header('Content-type','image/jpeg')
self.send_header('Content-length',str(tmpFile.len))
self.end_headers()
jpg.save(self.wfile,'JPEG')
time.sleep(0.05)
except KeyboardInterrupt:
break
return
if self.path.endswith('.html'):
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
self.wfile.write('<html><head></head><body>')
self.wfile.write('<img src="http://127.0.0.1:8080/cam.mjpg"/>')
self.wfile.write('</body></html>')
return
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
def main():
global capture
capture = cv2.VideoCapture(0)
# capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 320);
# capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 240);
# capture.set(cv2.cv.CV_CAP_PROP_SATURATION,0.2);
global img
try:
server = ThreadedHTTPServer(('localhost', 8080), CamHandler)
print("server started")
server.serve_forever()
except KeyboardInterrupt:
capture.release()
server.socket.close()
if __name__ == '__main__':
main()
##flaskを使った例
templatesフォルダ以下にindex.htmlを格納。
よくあるflaskの構造にしてください。
<html>
<head>
<title>Video Streaming Demonstration</title>
</head>
<body>
<h1>Video Streaming Demonstration</h1>
<img src="{{ url_for('video_feed') }}">
</body>
</html>
# -*- coding: utf-8 -*-
#python2
from flask import Flask, render_template, Response
#from camera import VideoCamera
from time import time
from PIL import Image
import cv2
import numpy as np
class Camera(object):
def __init__(self, cap):
rc,img = cap.read()
def get_frame(self):
self.frames = open("stream.jpg", 'w+')
s, img = cap.read()
if s: # frame captures without errors...
cv2.imwrite("stream.jpg", img) # Save image...
return self.frames.read()
cap=cv2.VideoCapture(0)
imagen = cap.read()
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
def gen(camera):
while True:
frame = camera.get_frame()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
@app.route('/video_feed')
def video_feed():
return Response(gen(Camera(cap)),
mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True, threaded=False)
#ブラウザからブラウザに転送する
p2pを簡単に使えるライブラリ。サーバーいらずでクライアント同士で通信できる。
詳しくいうと繋げる場合と繋げない場合があるようですが、今回はあまり深入りしません。
サンプルがいっぱいあるので面白い。
##WebRTC
https://webrtc.github.io/samples/
https://tech-sketch.jp/2014/07/webrtcpeerjs1.html
#C++の環境設定
##C++インストール(mac)
brew tap homebrew/science/
brew update
brew install opencv3 --with-contrib --with-python
brew install pkg-config
以下にインストールされてる
/usr/local/Celler/opencv3
cd /usr/local/Cellar/opencv3/3.1.0_4/lib/pkgconfig
sudo cp opencv.pc /usr/local/lib/pkgconfig/opencv.pc
opencv.pcをpkgconfig以下にコピーする。
#画像を表示する
#include <stdio.h>
#include <opencv2/opencv.hpp>
//g++ `pkg-config --cflags opencv` `pkg-config --libs opencv` 001.cpp -o 001
using namespace cv;
int main(int argc, char** argv ) {
Mat image;
image = imread("../../img/hari.jpeg", 1 );
if ( !image.data ) {
printf("No image data \n");
return -1;
}
namedWindow("Display Image", WINDOW_AUTOSIZE );
imshow("Display Image", image);
waitKey(0);
return 0;
}
g++ `pkg-config --cflags opencv` `pkg-config --libs opencv` 001.cpp -o 001
#OpenCV 2.2 チートシート (C++) どんな機能があるのかとかサラッと流す用です。
##OpenCV の重要なクラス
- Point 2 次元点クラステンプレート
- Point3 3 次元点クラステンプレート
- Size サイズ (幅,高さ) クラステンプレート
- Vec ショートベクトルクラステンプレート
- Matx 小型行列クラステンプレート
- Scalar 4-要素ベクトル
- Rect 矩形
- Range 整数値で表現される範囲
- Mat 2 次元 または 多次元の密な配(行列,画像,ヒストグラム,特徴ディスクリプタ,ボクセルボリュームなどを格納できます)
- SparseMat 多次元の疎な配列
- Ptr スマートポインタのクラステンプレート
##行列の基礎
###行列の作成
Mat image(240, 320, CV 8UC3);
###宣言済み行列の(再)配置
image.create(480, 640, CV 8UC3);
###行列を定数で初期化
Mat A33(3, 3, CV 32F, Scalar(5));
Mat B33(3, 3, CV 32F); B33 = Scalar(5);
Mat C33 = Mat::ones(3, 3, CV 32F)*5.;
Mat D33 = Mat::zeros(3, 3, CV 32F) + 5.;
###行列を特定の値で初期化
double a = CV PI/3;
Mat A22 = (Mat <float>(2, 2) <<
cos(a), -sin(a), sin(a), cos(a));
float B22data[] = {cos(a), -sin(a), sin(a), cos(a)};
Mat B22 = Mat(2, 2, CV 32F, B22data).clone();
###行列を乱数で初期化
randu(image, Scalar(0), Scalar(256)); // 一様分布
randn(image, Scalar(128), Scalar(10)); // 正規分布
###行列と他の構造体を互いに変換
(データコピーなし)
Mat image alias = image;
float* Idata=new float[480*640*3];
Mat I(480, 640, CV 32FC3, Idata);
vector<Point> iptvec(10);
Mat iP(iptvec); // iP – 10x1 CV 32SC2 matrix
IplImage* oldC0 = cvCreateImage(cvSize(320,240),16,1);
Mat newC = cvarrToMat(oldC0);
IplImage oldC1 = newC; CvMat oldC2 = newC;
###... (データコピーあり)
Mat newC2 = cvarrToMat(oldC0).clone();
vector<Point2f> ptvec = Mat <Point2f>(iP);
###行列の要素にアクセス
A33.at<float>(i,j) = A33.at<float>(j,i)+1;
Mat dyImage(image.size(), image.type());
for(int y = 1; y < image.rows-1; y++) {
Vec3b* prevRow = image.ptr<Vec3b>(y-1);
Vec3b* nextRow = image.ptr<Vec3b>(y+1);
for(int x = 0; y < image.cols; x++)
for(int c = 0; c < 3; c++)
dyImage.at<Vec3b>(y,x)[c] = saturate cast<uchar>(nextRow[x][c] - prevRow[x][c]);
}
Mat <Vec3b>::iterator it = image.begin<Vec3b>(),
itEnd = image.end<Vec3b>();
for(; it != itEnd; ++it)
(*it)[1] ^= 255;
##行列操作: コピー,シャッフル,部分行列
- src.copyTo(dst) 別の行列へのコピー
- src.convertTo(dst,type,scale,shift) スケーリングと別のデータ型への変換
- m.clone() 行列の深いコピー
- m.reshape(nch,nrows) データをコピーせずに,行列の次元,チャンネル数を変更
- m.row(i), m.col(i) 行列の行と列
- m.rowRange(Range(i1,i2))
m.colRange(Range(j1,j2)) 行列の行と列(範囲指定) - m.diag(i) 行列の対角要素
- m(Range(i1,i2),Range(j1,j2)),m(roi) 部分行列
- m.repeat(ny,nx) 小さい行列から大きな行列を作成
- flip(src,dst,dir) 行列の行(または列)の順序を反転
- split(...) マルチチャンネル行列を各チャンネル毎に分離
- merge(...) 各チャンネル毎の行列からマルチチャンネル行列を作成
- mixChannels(...) split() と merge() の一般型
- randShuffle(...) 行列の要素をランダムにシャッフル
例1. 画像 ROI を平滑化します
Mat imgroi = image(Rect(10, 20, 100, 100));
GaussianBlur(imgroi, imgroi, Size(5, 5), 1.2, 1.2);
例 2. 線形代数アルゴリズム
m.row(i) += m.row(j)*alpha;
例 3. 画像 ROI を別の画像に,変換しながらコピーします
Rect r(1, 1, 10, 20);
Mat dstroi = dst(Rect(0,10,r.width,r.height));
src(r).convertTo(dstroi, dstroi.type(), 1, 0);
##シンプルな行列操作
OpenCV には多くの一般的な,行列の算術演算,論理演算,その他の処理
が実装されています.例えば,
• add(), subtract(), multiply(), divide(), absdiff(),
bitwise and(), bitwise or(), bitwise xor(), max(), min(),
compare()
– 和や差,要素毎の掛け算 ... 二つの行列の比較や行列とスカラの比較,などに相当する演算.
例. アルファ合成 関数:
void alphaCompose(const Mat& rgba1, const Mat& rgba2, Mat& rgba dest)
{
Mat a1(rgba1.size(), rgba1.type()), ra1;
Mat a2(rgba2.size(), rgba2.type());
int mixch[]={3, 0, 3, 1, 3, 2, 3, 3};
mixChannels(&rgba1, 1, &a1, 1, mixch, 4);
mixChannels(&rgba2, 1, &a2, 1, mixch, 4);
subtract(Scalar::all(255), a1, ra1);
bitwise or(a1, Scalar(0,0,0,255), a1);
bitwise or(a2, Scalar(0,0,0,255), a2);
multiply(a2, ra1, a2, 1./255);
multiply(a1, rgba1, a1, 1./255);
multiply(a2, rgba2, a2, 1./255);
add(a1, a2, rgba dest);
}
• sum(), mean(), meanStdDev(), norm(), countNonZero(),minMaxLoc(),
– 行列要素の様々な統計量.
• exp(), log(), pow(), sqrt(), cartToPolar(), polarToCart()
– 古典的な算術関数.
• scaleAdd(), transpose(), gemm(), invert(), solve(),determinant(), trace() eigen(), SVD,
– 代数関数 + SVD クラス.
• dft(), idft(), dct(), idct(),
– 離散フーリエ変換,離散コサイン変換
さらに便利な 代数表記 が利用できる処理もあります.例えば:
Mat delta = (J.t()*J + lambda*
Mat::eye(J.cols, J.cols, J.type()))
.inv(CV SVD)*(J.t()*err);
これは,LeLevenberg-Marquardt 最適化アルゴリズムの要です.
##画像処理
###フィルタリング
- filter2D() 非分離型線形フィルタ
- sepFilter2D() 分離型線形フィルタ
- boxFilter(),GaussianBlur(),medianBlur(),bilateralFilter() 線形または非線形のフィルタを用いた画像の平滑化
- Sobel(), Scharr() 微分画像の計算
- Laplacian() ラプラシアンの計算
- erode(), dilate() 画像の収縮膨張
例. 3x3 のハイパスフィルタを適用します
(全体に 128 足して,負の値が失われないようにします):
filter2D(image, image, image.depth(), (Mat <float>(3,3)<<
-1, -1, -1, -1, 9, -1, -1, -1, -1), Point(1,1), 128);
##幾何学変換
- resize() 画像のリサイズ
- getRectSubPix() 画像パッチの抽出
- warpAffine() 画像のアフィン変換
- warpPerspective() 画像の透視変換
- remap() 汎用的な画像変換
- convertMaps() remap() を高速に実行するためのマップ最適化
例.
ルート2 分の一に画像を縮小します:
Mat dst; resize(src, dst, Size(), 1./sqrt(2), 1./sqrt(2));
##様々な画像変換
- cvtColor() 画像を別の色空間に変換
- threshold(),adaptivethreshold() 固定あるいは可変の閾値を用いて,グレースケール画像を 2 値画像に変換
- floodFill() 領域拡張アルゴリズムを用いた,連結成分の検出
- integral() インテグラルイメージの計算
- distanceTransform() 2 値画像に対する,距離画像またはボロノイ図の構築
- watershed(), grabCut() マーカベースの画像セグメンテーションアルゴリズム watershed.cpp や grabcut.cpp のサンプルを参照してください.
##ヒストグラム
- calcHist() 画像のヒストグラムの計算
- calcBackProject() ヒストグラムの逆投影
- equalizeHist() 画像の明るさとコントラストの正規化
- compareHist() 2 つのヒストグラムの比較
例. 画像の色相-彩度ヒストグラムを計算します:
Mat hsv, H; MatND tempH;
cvtColor(image, hsv, CV BGR2HSV);
int planes[]={0, 1}, hsize[] = {32, 32};
calcHist(&hsv, 1, planes, Mat(), tempH, 2, hsize, 0);
H = tempH;
##輪郭
輪郭の意味や使い方については contours.cpp や squares.cpp のサンプルを参照してください.
データの入出力
XML/YAML ストレージ は(入れ子可能な)コレクションで,スカラ値,構造体,様々なリストを含むことができます.
##YAML(または XML)へのデータの書き込み
// ファイルの種類は拡張子によって決められます
FileStorage fs("test.yml", FileStorage::WRITE);
fs << "i" << 5 << "r" << 3.1 << "str" << "ABCDEFGH";
fs << "mtx" << Mat::eye(3,3,CV 32F);
fs << "mylist" << "[" << CV PI << "1+1" <<
"{:" << "month" << 12 << "day" << 31 << "year"
<< 1969 << "}" << "]";
fs << "mystruct" << "{" << "x" << 1 << "y" << 2 <<
"width" << 100 << "height" << 200 << "lbp" << "[:";
const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1};
fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0])));
fs << "]" << "}";
<< 演算子を用いて,スカラ値 (整数,浮動小数点数,文字列),行列,ス
カラ値やその他の型の STL vector をファイルストレージに書き込むこと
ができます
データの読み出し
// ファイルの種類は内容によって決められます
FileStorage fs("test.yml", FileStorage::READ);
int i1 = (int)fs["i"]; double r1 = (double)fs["r"];
string str1 = (string)fs["str"];
Mat M; fs["mtx"] >> M;
FileNode tl = fs["mylist"];
CV Assert(tl.type() == FileNode::SEQ && tl.size() == 3);
double tl0 = (double)tl[0]; string tl1 = (string)tl[1];
int m = (int)tl[2]["month"], d = (int)tl[2]["day"];
int year = (int)tl[2]["year"];
FileNode tm = fs["mystruct"];
Rect r; r.x = (int)tm["x"], r.y = (int)tm["y"];
r.width = (int)tm["width"], r.height = (int)tm["height"];
int lbp val = 0;
FileNodeIterator it = tm["lbp"].begin();
for(int k = 0; k < 8; k++, ++it)
lbp val |= ((int)*it) << k;
FileNode のキャスト演算子を用いて,スカラ値を読み込みます.行列やそ
の他の型は, >> 演算子を用いて読み込みます.リストを読み込む場合は,
FileNodeIterator を利用します.
ラスタ画像の書き込みと読み込み
imwrite("myimage.jpg", image);
Mat image color copy = imread("myimage.jpg", 1);
Mat image grayscale copy = imread("myimage.jpg", 0);
これらの関数が読み書き可能なフォーマット: BMP (.bmp), JPEG
(.jpg, .jpeg), TIFF (.tif, .tiff), PNG (.png), PBM/PGM/PPM
(.p?m), Sun Raster (.sr), JPEG 2000 (.jp2). 各フォーマットは,
8 ビット,1- または 3-チャンネルの画像をサポートします.1 チャンネル
が 16 ビットの画像をサポートするフォーマット (PNG, JPEG 2000) も
あります.
動画ファイルやカメラから画像を読み込みます
VideoCapture cap;
if(argc > 1) cap.open(string(argv[1])); else cap.open(0);
Mat frame; namedWindow("video", 1);
for(;;) {
cap >> frame; if(!frame.data) break;
imshow("video", frame); if(waitKey(30) >= 0) break;
}
##シンプル GUI(highgui モジュール)
- namedWindow(winname,flags)名前付き highgui ウィンドウを作成します
- destroyWindow(winname) 指定したウィンドウを破棄します
- imshow(winname, mtx) ウィンドウ内に画像を表示します
- waitKey(delay) 指定時間だけ(あるいは永遠に)キーが押されるのを待ちます.待ち時間にイベントの処理を行います. この関数を,1 秒間に数回程度呼び出すの
を忘れないように. - createTrackbar(...) 指定したウィンドウにトラックバー(スライダー)を追加します.
- setMouseCallback(...) 指定したウィンドウ内でのマウスのクリックと移動に対して,コールバックを設定します.
GUI 関数の使い方については, camshiftdemo.cpp や OpenCV
samples を参照してください.
##カメラキャリブレーション,姿勢推定,奥行き推定
- calibrateCamera() キャリブレーションパターンを写した複数枚の画像を用いて,カメラをキャリブレーションします.
- findChessboardCorners() チェッカーボードキャリブレーションパターン上の特徴点を検出します.
- solvePnP() その特徴点を投影した結果から,元の物体の姿勢を求めます.
- stereoCalibrate() ステレオカメラをキャリブレーションします.
- stereoRectify() キャリブレーションされたステレオカメラ画像の平行化を行います.
- initUndistortRectifyMap() ステレオカメラの各カメラに対する, ( remap() 用の )平行化マップを計算します.
- StereoBM, StereoSGBM 平行化されたステレオペア上で実行される,ステレオ対応点探索エンジンです.
- reprojectImageTo3D() 視差マップを 3 次元点群に変換します.
- findHomography() 2 次元点集合間の最適な透視変換を求めます.
カメラをキャリブレーションするには,サンプル calibration.cpp やstereo calib.cpp を利用できます.視差マップや 3 次元点群を得るには,サンプル stereo match.cpp を利用してください.
##物体検出
- matchTemplate 入力テンプレートに対する一致度マップを求めます.
- CascadeClassifier Viola が提唱した Haar や LBP 特徴量を利用するブースティング分類器のカスケードです.
facedetect.cpp を参照してください. - HOGDescriptor N. Dalal が提唱した HOG 特徴量を利用する物
体検出器です.peopledetect.cpp を参照してく
ださい.
#気になるページ
nodeで動画をサーバーに送信
https://github.com/na2hiro/webrtc-distribution
opencvのストーリミングのスピードをあげる
http://nobutobook.blogspot.jp/2016/10/python-opencv.html
face tracking
https://01.org/developerjourney/face-tracking
https://realpython.com/blog/python/face-detection-in-python-using-a-webcam/
http://manmade2.com/simple-home-surveillance-with-opencv-python-and-raspberry-pi/
Python live browser surveillance with motion detection
https://github.com/Arri/Py_WebSurveillance
streamming
https://svds.com/streaming-video-analysis-python/
motion track
https://github.com/svetlichnaya/Motion-Tracking
rgbからlow color hight colorに変換
https://henrydangprg.com/2016/06/26/color-detection-in-python-with-opencv/
#参考
https://www.pro-s.co.jp/engineerblog/opencv/post_6231.html
http://qiita.com/hitomatagi/items/04b1b26c1bc2e8081427
http://derivecv.tumblr.com/post/73561473978
http://opencv.jp/opencv-2svn/opencv_cheatsheet.pdf
C++環境まわり
http://www2.meijo-u.ac.jp/~kohara/cms/technicalreport/opencv_intall4mac
http://purple-apple.hatenadiary.jp/entry/2017/02/05/195109