OpenCV OpticalFlow - eiichiromomma/CVMLAB GitHub Wiki
(OpenCV) Optical flow
USBカメラでオプティカルフロー
opencv.jp - OpenCV: オプティカルフロー(Optical flow)サンプルコード - を参考に作成。 videoInputでやりたい場合は最初と最後の宣言とフレームの取得だけ書換えれば良い。
![](https://github.com/eiichiromomma/CVMLAB/blob/master/img/cvOptFlow01.gif
PyrLK→BM→LK→HSの順で変えてみた。チューニングは殆どしていない。
1,2,3,4キーでHS、LK、BM、PyrLK(デフォルト)に切り替わる。 ESCで終了。
Linuxの場合はSleepの個所を書換えること
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
enum{
OPT_X_STEP = 5,
OPT_Y_STEP = 5,
HS_LAMBDA = 100,
LK_SIZE = 15,
//BMは時間が掛かるので動画で使うにはチューニングが必要
//マッチングテンプレートの大きさ
BM_BLOCK = 10,
//マッチング時の間引き量(1だと間引き無し)
BM_SHIFT = 3,
//マッチングの探索範囲
BM_MAX = 50,
//PyrLK用
PYRLK_COUNT = 150
};
void main(void)
{
int x,y;
IplImage* currImg = NULL;
IplImage* currBImg = NULL;
IplImage* currGImg = NULL;
IplImage* currRImg = NULL;
IplImage* prevBImg = NULL;
IplImage* prevGImg = NULL;
IplImage* prevRImg = NULL;
IplImage* opImg = NULL;
CvCapture* cap = cvCreateCameraCapture(0);
if (cap == NULL){
return;
}
//USBカメラの始動待ち(Windows)
Sleep(100);
currImg = cvQueryFrame(cap);
//オプティカルフローの算出は1ch画像が必要
//ループのためにダミーフレームを取得しておく
currGImg = cvCreateImage(cvGetSize(currImg),currImg->depth, 1);
currBImg = cvCloneImage(currGImg);
currRImg = cvCloneImage(currGImg);
prevBImg = cvCloneImage(currGImg);
prevGImg = cvCloneImage(currGImg);
prevRImg = cvCloneImage(currGImg);
//B,G,Rに分離
cvSplit(currImg,currBImg,currGImg,currRImg,NULL);
opImg = cvCloneImage(currImg);
//各色用のベクトル置場
CvMat* vxB = cvCreateMat(currImg->height, currImg->width, CV_32FC1);
CvMat* vyB = cvCreateMat(currImg->height, currImg->width, CV_32FC1);
CvMat* vxG = cvCreateMat(currImg->height, currImg->width, CV_32FC1);
CvMat* vyG = cvCreateMat(currImg->height, currImg->width, CV_32FC1);
CvMat* vxR = cvCreateMat(currImg->height, currImg->width, CV_32FC1);
CvMat* vyR = cvCreateMat(currImg->height, currImg->width, CV_32FC1);
cvSetZero(vxB);
cvSetZero(vyB);
cvSetZero(vxG);
cvSetZero(vyG);
cvSetZero(vxR);
cvSetZero(vyR);
//BM用の置場
//ブロックサイズで割った大きさになる
CvMat* vxB_BM = cvCreateMat(int(ceil(double(currImg->height) / BM_BLOCK)), int(ceil(double(currImg->width) / BM_BLOCK)), CV_32FC1);
CvMat* vyB_BM = cvCreateMat(int(ceil(double(currImg->height) / BM_BLOCK)), int(ceil(double(currImg->width) / BM_BLOCK)), CV_32FC1);
CvMat* vxG_BM = cvCreateMat(int(ceil(double(currImg->height) / BM_BLOCK)), int(ceil(double(currImg->width) / BM_BLOCK)), CV_32FC1);
CvMat* vyG_BM = cvCreateMat(int(ceil(double(currImg->height) / BM_BLOCK)), int(ceil(double(currImg->width) / BM_BLOCK)), CV_32FC1);
CvMat* vxR_BM = cvCreateMat(int(ceil(double(currImg->height) / BM_BLOCK)), int(ceil(double(currImg->width) / BM_BLOCK)), CV_32FC1);
CvMat* vyR_BM = cvCreateMat(int(ceil(double(currImg->height) / BM_BLOCK)), int(ceil(double(currImg->width) / BM_BLOCK)), CV_32FC1);
//PyrLK用の画像と置場置場
int corner_countB = PYRLK_COUNT;
int corner_countG = PYRLK_COUNT;
int corner_countR = PYRLK_COUNT;
IplImage* eig_imageB = cvCreateImage(cvGetSize(currImg),IPL_DEPTH_32F,1);
IplImage* temp_imageB = cvCloneImage(eig_imageB);
IplImage* eig_imageG = cvCreateImage(cvGetSize(currImg),IPL_DEPTH_32F,1);
IplImage* temp_imageG = cvCloneImage(eig_imageG);
IplImage* eig_imageR = cvCreateImage(cvGetSize(currImg),IPL_DEPTH_32F,1);
IplImage* temp_imageR = cvCloneImage(eig_imageR);
CvPoint2D32f* corners1B = (CvPoint2D32f *) cvAlloc (corner_countB * sizeof (CvPoint2D32f));
CvPoint2D32f* corners2B = (CvPoint2D32f *) cvAlloc (corner_countB * sizeof (CvPoint2D32f));
CvPoint2D32f* corners1G = (CvPoint2D32f *) cvAlloc (corner_countG * sizeof (CvPoint2D32f));
CvPoint2D32f* corners2G = (CvPoint2D32f *) cvAlloc (corner_countG * sizeof (CvPoint2D32f));
CvPoint2D32f* corners1R = (CvPoint2D32f *) cvAlloc (corner_countR * sizeof (CvPoint2D32f));
CvPoint2D32f* corners2R = (CvPoint2D32f *) cvAlloc (corner_countR * sizeof (CvPoint2D32f));
IplImage* prev_pyramidB = cvCreateImage (cvSize (currImg->width + 8, currImg->height / 3), IPL_DEPTH_8U, 1);
IplImage* curr_pyramidB = cvCreateImage (cvSize (currImg->width + 8, currImg->height / 3), IPL_DEPTH_8U, 1);
IplImage* prev_pyramidG = cvCreateImage (cvSize (currImg->width + 8, currImg->height / 3), IPL_DEPTH_8U, 1);
IplImage* curr_pyramidG = cvCreateImage (cvSize (currImg->width + 8, currImg->height / 3), IPL_DEPTH_8U, 1);
IplImage* prev_pyramidR = cvCreateImage (cvSize (currImg->width + 8, currImg->height / 3), IPL_DEPTH_8U, 1);
IplImage* curr_pyramidR = cvCreateImage (cvSize (currImg->width + 8, currImg->height / 3), IPL_DEPTH_8U, 1);
char* statusB = (char *) cvAlloc (corner_countB);
char* statusG = (char *) cvAlloc (corner_countG);
char* statusR = (char *) cvAlloc (corner_countR);
//止め時は試行錯誤が必要。
//CV_TERMCRIT_ITERは試行回数で制限
//CV_TERMCRIT_EPSは誤差で制限
//オプティカルフローを厳密に求める場合は後者を
//速く求める場合は前者を、中間を取りたければORで指定し両方の何れかとする
CvTermCriteria termcrit = cvTermCriteria(CV_TERMCRIT_ITER,50,0.1);
cvNamedWindow("currImg",1);
cvNamedWindow("opImg",1);
cvShowImage("currImg",currImg);
fputs("1: HS\n2: LK\n3: BM\n4: PyrLK\nESC: Quit",stderr);
int key=0;
int method = 4;
while (27 != key){
cvCopyImage(currBImg,prevBImg);
cvCopyImage(currGImg,prevGImg);
cvCopyImage(currRImg,prevRImg);
currImg = cvQueryFrame(cap);
cvSplit(currImg,currBImg,currGImg,currRImg,NULL);
cvCopyImage(currImg,opImg);
switch(method){
case 1:
//HSの場合
cvCalcOpticalFlowHS(prevBImg,currBImg, 0, vxB, vyB, HS_LAMBDA, termcrit);
cvCalcOpticalFlowHS(prevGImg,currGImg, 0, vxG, vyG, HS_LAMBDA, termcrit);
cvCalcOpticalFlowHS(prevRImg,currRImg, 0, vxR, vyR, HS_LAMBDA, termcrit);
for (y = 0; y< currImg->height; y+=OPT_Y_STEP){
for (x = 0; x< currImg->width; x+=OPT_X_STEP){
cvLine(opImg, cvPoint(x,y), cvPoint(x+ cvGetReal2D(vxB,y,x), y+ cvGetReal2D(vyB,y,x)),CV_RGB(0,0,255));
cvLine(opImg, cvPoint(x,y), cvPoint(x+ cvGetReal2D(vxG,y,x), y+ cvGetReal2D(vyG,y,x)),CV_RGB(0,255,0));
cvLine(opImg, cvPoint(x,y), cvPoint(x+ cvGetReal2D(vxR,y,x), y+ cvGetReal2D(vyR,y,x)),CV_RGB(255,0,0));
}
}
break;
case 2:
//LKの場合
cvCalcOpticalFlowLK(prevBImg,currBImg, cvSize(LK_SIZE,LK_SIZE), vxB, vyB);
cvCalcOpticalFlowLK(prevGImg,currGImg, cvSize(LK_SIZE,LK_SIZE), vxG, vyG);
cvCalcOpticalFlowLK(prevRImg,currRImg, cvSize(LK_SIZE,LK_SIZE), vxR, vyR);
for (y = 0; y< currImg->height; y+=OPT_Y_STEP){
for (x = 0; x< currImg->width; x+=OPT_X_STEP){
cvLine(opImg, cvPoint(x,y), cvPoint(x+ cvGetReal2D(vxB,y,x), y+ cvGetReal2D(vyB,y,x)),CV_RGB(0,0,255));
cvLine(opImg, cvPoint(x,y), cvPoint(x+ cvGetReal2D(vxG,y,x), y+ cvGetReal2D(vyG,y,x)),CV_RGB(0,255,0));
cvLine(opImg, cvPoint(x,y), cvPoint(x+ cvGetReal2D(vxR,y,x), y+ cvGetReal2D(vyR,y,x)),CV_RGB(255,0,0));
}
}
break;
case 3:
//BMの場合
cvCalcOpticalFlowBM(prevBImg,currBImg,cvSize(BM_BLOCK,BM_BLOCK),cvSize(BM_SHIFT,BM_SHIFT),cvSize(BM_MAX,BM_MAX),0,vxB_BM,vyB_BM);
cvCalcOpticalFlowBM(prevGImg,currGImg,cvSize(BM_BLOCK,BM_BLOCK),cvSize(BM_SHIFT,BM_SHIFT),cvSize(BM_MAX,BM_MAX),0,vxG_BM,vyG_BM);
cvCalcOpticalFlowBM(prevRImg,currRImg,cvSize(BM_BLOCK,BM_BLOCK),cvSize(BM_SHIFT,BM_SHIFT),cvSize(BM_MAX,BM_MAX),0,vxR_BM,vyR_BM);
for (y = 0; y< vxB_BM->rows; y++){
for (x = 0; x< vxB_BM->cols; x++){
cvLine(opImg, cvPoint(x*BM_BLOCK,y*BM_BLOCK), cvPoint(x*BM_BLOCK+ cvGetReal2D(vxB_BM,y,x), y*BM_BLOCK+ cvGetReal2D(vyB_BM,y,x)),CV_RGB(0,0,255));
cvLine(opImg, cvPoint(x*BM_BLOCK,y*BM_BLOCK), cvPoint(x*BM_BLOCK+ cvGetReal2D(vxG_BM,y,x), y*BM_BLOCK+ cvGetReal2D(vyG_BM,y,x)),CV_RGB(0,255,0));
cvLine(opImg, cvPoint(x*BM_BLOCK,y*BM_BLOCK), cvPoint(x*BM_BLOCK+ cvGetReal2D(vxR_BM,y,x), y*BM_BLOCK+ cvGetReal2D(vyR_BM,y,x)),CV_RGB(255,0,0));
}
}
break;
case 4:
//PyrLKの場合
cvGoodFeaturesToTrack (currBImg, eig_imageB, temp_imageB, corners1B, &corner_countB, 0.001, 5, NULL);
cvGoodFeaturesToTrack (currGImg, eig_imageG, temp_imageG, corners1G, &corner_countG, 0.001, 5, NULL);
cvGoodFeaturesToTrack (currRImg, eig_imageR, temp_imageR, corners1R, &corner_countR, 0.001, 5, NULL);
cvCalcOpticalFlowPyrLK(prevBImg, currBImg, prev_pyramidB, curr_pyramidB, corners1B, corners2B, corner_countB, cvSize(LK_SIZE,LK_SIZE), 4, statusB, NULL,termcrit, 0);
cvCalcOpticalFlowPyrLK(prevGImg, currGImg, prev_pyramidG, curr_pyramidG, corners1G, corners2G, corner_countG, cvSize(LK_SIZE,LK_SIZE), 4, statusG, NULL,termcrit, 0);
cvCalcOpticalFlowPyrLK(prevRImg, currRImg, prev_pyramidR, curr_pyramidR, corners1R, corners2R, corner_countR, cvSize(LK_SIZE,LK_SIZE), 4, statusR, NULL,termcrit, 0);
for (x=0; x<corner_countB; x++){
if (statusB[x]){
cvLine(opImg,cvPointFrom32f(corners1B[x]),cvPointFrom32f(corners2B[x]),CV_RGB(255,0,0));
}
if (statusG[x]){
cvLine(opImg,cvPointFrom32f(corners1G[x]),cvPointFrom32f(corners2G[x]),CV_RGB(0,255,0));
}
if (statusR[x]){
cvLine(opImg,cvPointFrom32f(corners1R[x]),cvPointFrom32f(corners2R[x]),CV_RGB(0,0,255));
}
}
break;
default:
break;
}
cvShowImage("currImg",currImg);
cvShowImage("opImg",opImg);
key = cvWaitKey(10);
switch(key){
case '1':
method = 1;
break;
case '2':
method = 2;
break;
case '3':
method = 3;
break;
case '4':
method = 4;
break;
default:
break;
}
}
cvReleaseCapture(&cap);
}
cvAllocのListへの置き換えがミソか。 うちの環境ではキャプチャデバイスの解放が怪しいのでPythonシェルを強制終了する必要がある。 あとPythonはcvcamの方を使っているようなので、C++とは挙動が異なりcvFlipを入れる必要がある場合も。 あとBMでの計算が変。面倒なのでよく見てない。
from opencv.cv import *
from opencv.highgui import *
import sys
import ctypes
import math
def main():
OPT_X_STEP = 5
OPT_Y_STEP = 5
HS_LAMBDA = 100
LK_SIZE = 15
BM_BLOCK = 10
BM_SHIFT = 3
BM_MAX = 50
PYRLK_COUNT = 150
x=0
y=0
cap = cvCreateCameraCapture(0)
currImg = cvQueryFrame(cap)
currGImg = cvCreateImage(cvGetSize(currImg),currImg.depth, 1)
currBImg = cvCloneImage(currGImg)
currRImg = cvCloneImage(currGImg)
prevBImg = cvCloneImage(currGImg)
prevGImg = cvCloneImage(currGImg)
prevRImg = cvCloneImage(currGImg)
cvSplit(currImg,currBImg,currGImg,currRImg,None)
opImg = cvCloneImage(currImg)
#各色用のベクトル置場
vxB = cvCreateMat(currImg.height, currImg.width, CV_32FC1)
vyB = cvCreateMat(currImg.height, currImg.width, CV_32FC1)
vxG = cvCreateMat(currImg.height, currImg.width, CV_32FC1)
vyG = cvCreateMat(currImg.height, currImg.width, CV_32FC1)
vxR = cvCreateMat(currImg.height, currImg.width, CV_32FC1)
vyR = cvCreateMat(currImg.height, currImg.width, CV_32FC1)
cvSetZero(vxB)
cvSetZero(vyB)
cvSetZero(vxG)
cvSetZero(vyG)
cvSetZero(vxR)
cvSetZero(vyR)
#BM用の置場
#ブロックサイズで割った大きさになる
vxB_BM = cvCreateMat(int(math.ceil(float(currImg.height) / BM_BLOCK)), int(math.ceil(float(currImg.width) / BM_BLOCK)), CV_32FC1)
vyB_BM = cvCreateMat(int(math.ceil(float(currImg.height) / BM_BLOCK)), int(math.ceil(float(currImg.width) / BM_BLOCK)), CV_32FC1)
vxG_BM = cvCreateMat(int(math.ceil(float(currImg.height) / BM_BLOCK)), int(math.ceil(float(currImg.width) / BM_BLOCK)), CV_32FC1)
vyG_BM = cvCreateMat(int(math.ceil(float(currImg.height) / BM_BLOCK)), int(math.ceil(float(currImg.width) / BM_BLOCK)), CV_32FC1)
vxR_BM = cvCreateMat(int(math.ceil(float(currImg.height) / BM_BLOCK)), int(math.ceil(float(currImg.width) / BM_BLOCK)), CV_32FC1)
vyR_BM = cvCreateMat(int(math.ceil(float(currImg.height) / BM_BLOCK)), int(math.ceil(float(currImg.width) / BM_BLOCK)), CV_32FC1)
#PyrLK用の画像と置場
corner_countB = PYRLK_COUNT
corner_countG = PYRLK_COUNT
corner_countR = PYRLK_COUNT
eig_imageB = cvCreateImage(cvGetSize(currImg),IPL_DEPTH_32F,1)
temp_imageB = cvCloneImage(eig_imageB)
eig_imageG = cvCreateImage(cvGetSize(currImg),IPL_DEPTH_32F,1)
temp_imageG = cvCloneImage(eig_imageG)
eig_imageR = cvCreateImage(cvGetSize(currImg),IPL_DEPTH_32F,1)
temp_imageR = cvCloneImage(eig_imageR)
prev_pyramidB = cvCreateImage (cvSize (currImg.width + 8, currImg.height / 3), IPL_DEPTH_8U, 1)
curr_pyramidB = cvCreateImage (cvSize (currImg.width + 8, currImg.height / 3), IPL_DEPTH_8U, 1)
prev_pyramidG = cvCreateImage (cvSize (currImg.width + 8, currImg.height / 3), IPL_DEPTH_8U, 1)
curr_pyramidG = cvCreateImage (cvSize (currImg.width + 8, currImg.height / 3), IPL_DEPTH_8U, 1)
prev_pyramidR = cvCreateImage (cvSize (currImg.width + 8, currImg.height / 3), IPL_DEPTH_8U, 1)
curr_pyramidR = cvCreateImage (cvSize (currImg.width + 8, currImg.height / 3), IPL_DEPTH_8U, 1)
#止め時は試行錯誤が必要。
#CV_TERMCRIT_ITERは試行回数で制限
#CV_TERMCRIT_EPSは誤差で制限
#オプティカルフローを厳密に求める場合は後者を
#速く求める場合は前者を、中間を取りたければORで指定し両方の何れかとする
termcrit = cvTermCriteria(CV_TERMCRIT_ITER,50,0.1)
cvNamedWindow("currImg",1)
cvNamedWindow("opImg",1)
cvShowImage("currImg",currImg)
print("1: HS\n2: LK\n3: BM\n4: PyrLK\nESC: Quit")
key=0
method = 4
#pointsLK_?が各色の[注目点[]、移動先[]]となる
pointsLK_B = [[],[]]
pointsLK_G = [[],[]]
pointsLK_R = [[],[]]
while '\x1b' != key :
cvCopy(currBImg,prevBImg)
cvCopy(currGImg,prevGImg)
cvCopy(currRImg,prevRImg)
currImg = cvQueryFrame(cap)
cvSplit(currImg,currBImg,currGImg,currRImg,None)
cvCopy(currImg,opImg)
if method == 1:
#HSの場合
cvCalcOpticalFlowHS(prevBImg,currBImg, 0, vxB, vyB, HS_LAMBDA, termcrit)
cvCalcOpticalFlowHS(prevGImg,currGImg, 0, vxG, vyG, HS_LAMBDA, termcrit)
cvCalcOpticalFlowHS(prevRImg,currRImg, 0, vxR, vyR, HS_LAMBDA, termcrit)
for y in range( 0, currImg.height, OPT_Y_STEP):
for x in range(0, currImg.width, OPT_X_STEP):
cvLine(opImg, cvPoint(x,y), cvPoint(x+ int(cvGetReal2D(vxB,y,x)), y+ int(cvGetReal2D(vyB,y,x))),CV_RGB(0,0,255))
cvLine(opImg, cvPoint(x,y), cvPoint(x+ int(cvGetReal2D(vxG,y,x)), y+ int(cvGetReal2D(vyG,y,x))),CV_RGB(0,255,0))
cvLine(opImg, cvPoint(x,y), cvPoint(x+ int(cvGetReal2D(vxR,y,x)), y+ int(cvGetReal2D(vyR,y,x))),CV_RGB(255,0,0))
elif method == 2:
#LKの場合
cvCalcOpticalFlowLK(prevBImg,currBImg, cvSize(LK_SIZE,LK_SIZE), vxB, vyB)
cvCalcOpticalFlowLK(prevGImg,currGImg, cvSize(LK_SIZE,LK_SIZE), vxG, vyG)
cvCalcOpticalFlowLK(prevRImg,currRImg, cvSize(LK_SIZE,LK_SIZE), vxR, vyR)
for y in range(0, currImg.height, OPT_Y_STEP):
for x in range(0, currImg.width, OPT_X_STEP):
cvLine(opImg, cvPoint(x,y), cvPoint(x+ int(cvGetReal2D(vxB,y,x)), y+ int(cvGetReal2D(vyB,y,x))),CV_RGB(0,0,255))
cvLine(opImg, cvPoint(x,y), cvPoint(x+ int(cvGetReal2D(vxG,y,x)), y+ int(cvGetReal2D(vyG,y,x))),CV_RGB(0,255,0))
cvLine(opImg, cvPoint(x,y), cvPoint(x+ int(cvGetReal2D(vxR,y,x)), y+ int(cvGetReal2D(vyR,y,x))),CV_RGB(255,0,0))
elif method == 3:
#BMの場合
cvCalcOpticalFlowBM(prevBImg,currBImg,cvSize(BM_BLOCK,BM_BLOCK),cvSize(BM_SHIFT,BM_SHIFT),cvSize(BM_MAX,BM_MAX),0,vxB_BM,vyB_BM)
cvCalcOpticalFlowBM(prevGImg,currGImg,cvSize(BM_BLOCK,BM_BLOCK),cvSize(BM_SHIFT,BM_SHIFT),cvSize(BM_MAX,BM_MAX),0,vxG_BM,vyG_BM)
cvCalcOpticalFlowBM(prevRImg,currRImg,cvSize(BM_BLOCK,BM_BLOCK),cvSize(BM_SHIFT,BM_SHIFT),cvSize(BM_MAX,BM_MAX),0,vxR_BM,vyR_BM)
for y in range(0, vxB_BM.rows):
for x in range(0, vxB_BM.cols):
cvLine(opImg, cvPoint(x*BM_BLOCK,y*BM_BLOCK), cvPoint(x*BM_BLOCK+ int(cvGetReal2D(vxB_BM,y,x)), y*BM_BLOCK+ int(cvGetReal2D(vyB_BM,y,x))),CV_RGB(0,0,255))
cvLine(opImg, cvPoint(x*BM_BLOCK,y*BM_BLOCK), cvPoint(x*BM_BLOCK+ int(cvGetReal2D(vxG_BM,y,x)), y*BM_BLOCK+ int(cvGetReal2D(vyG_BM,y,x))),CV_RGB(0,255,0))
cvLine(opImg, cvPoint(x*BM_BLOCK,y*BM_BLOCK), cvPoint(x*BM_BLOCK+ int(cvGetReal2D(vxR_BM,y,x)), y*BM_BLOCK+ int(cvGetReal2D(vyR_BM,y,x))),CV_RGB(255,0,0))
elif method == 4:
#PyrLKの場合
#cvGoodFeaturesToTrackの返り値はpoints[]
pointsLK_B[0] = cvGoodFeaturesToTrack (currBImg, eig_imageB, temp_imageB, corner_countB, 0.001, 5, None)
pointsLK_G[0] = cvGoodFeaturesToTrack (currGImg, eig_imageG, temp_imageG, corner_countG, 0.001, 5, None)
pointsLK_R[0] = cvGoodFeaturesToTrack (currRImg, eig_imageR, temp_imageR, corner_countR, 0.001, 5, None)
#cvCalcOpticalFlowPyrLKの返り値はpoints[],status[]になる
pointsLK_B[1],statusB = cvCalcOpticalFlowPyrLK(prevBImg, currBImg, prev_pyramidB, curr_pyramidB, pointsLK_B[0], len(pointsLK_B[0]), cvSize(LK_SIZE,LK_SIZE), 4, len(pointsLK_B[0]), None,termcrit, 0)
pointsLK_G[1],statusG = cvCalcOpticalFlowPyrLK(prevGImg, currGImg, prev_pyramidG, curr_pyramidG, pointsLK_G[0], len(pointsLK_G[0]), cvSize(LK_SIZE,LK_SIZE), 4, len(pointsLK_G[0]), None,termcrit, 0)
pointsLK_R[1],statusR = cvCalcOpticalFlowPyrLK(prevRImg, currRImg, prev_pyramidR, curr_pyramidR, pointsLK_R[0], len(pointsLK_R[0]), cvSize(LK_SIZE,LK_SIZE), 4, len(pointsLK_R[0]), None,termcrit, 0)
#PythonではListは1次元のみなので、宣言は[[],[]]としても[0,1]とは呼べない(らしい)
#一旦PointsのListへListをコピーして参照させる
#Blue
points_c0 = len(pointsLK_B[0])
p0 =pointsLK_B[0]
p1 = pointsLK_B[1]
for i in range(points_c0):
if statusB[i]:
cvLine(opImg,cvPointFrom32f(p0[i]),cvPointFrom32f(p1[i]),CV_RGB(0,0,255))
#Green
points_c0 = len(pointsLK_G[0])
p0 =pointsLK_G[0]
p1 = pointsLK_G[1]
for i in range(points_c0):
if statusG[i]:
cvLine(opImg,cvPointFrom32f(p0[i]),cvPointFrom32f(p1[i]),CV_RGB(0,255,0))
#Red
points_c0 = len(pointsLK_G[0])
p0 =pointsLK_R[0]
p1 = pointsLK_R[1]
for i in range(points_c0):
if statusR[i]:
cvLine(opImg,cvPointFrom32f(p0[i]),cvPointFrom32f(p1[i]),CV_RGB(255,0,0))
cvShowImage("currImg",currImg)
cvShowImage("opImg",opImg)
key = cvWaitKey(50)
if key == '\x31':
method = 1
print "HS"
elif key == '\x32':
method = 2
print "LK"
elif key == '\x33':
method = 3
print "BM"
elif key == '\x34':
method = 4
print "PyrLK"
cvDestroyWindow("currImg")
cvDestroyWindow("opImg")
if __name__ == '__main__':
main()