컴퓨터비전/영상처리
옵티컬 플로우 Optical Flow -1
object0814
2015. 4. 4. 22:28
어떤 물체를 추적할때 가장 간단한 방법이 해당 블록(영역)을 다음 프레임에서 어딨을지 찾아가는
방법이 가장 간단한 추적 방법일 것이다.
OpenCV에서는 이 방법을 하나의 메소드 형태로 제공한다.
1 2 | void cvCalcOpticalFlowBM(const CvArr* prev, const CvArr* curr, CvSize block_size, CvSize shift_size, CvSize max_range, int use_previous, CvArr* velx, CvArr* vely) | cs |
파라메타로 prev는 이전프레임으로 (8비트, 1채널 영상)을 입력받으며, curr는 현재 프레임으로
이전 프레임과 동일하게 8비트 1채널 영상을 입력 받는다.
block_size는 두 영상에서 비교할 블록의 크기를 의미하며, shift_size는 탐색할 영역 크기를 나타낸다.
velx와 vely는 속도 벡터를 나타내는 변수로 1채널 32비트 실수 영상이다.
max_range는 curr에서 최대 탐색 범위를 나타내고 usePreviosu가 1이면 velx와 vely에 있는 이전 결과를 사용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #include <cv.h> #include <highgui.h> #include <opencv\cvaux.h> int main() { IplImage *prev = NULL, *curr = NULL; IplImage *velx = NULL, *vely = NULL; prev = cvLoadImage("img/prev.bmp", 0); curr = cvLoadImage("img/curr.bmp", 0); CvSize block_Size = cvSize(10, 10); CvSize shift_size = cvSize(5, 5); CvSize max_range = cvSize(5, 5); int usePrevious = 0; int sX = (prev->width - block_Size.width) / shift_size.width + 1; int sY = (prev->height - block_Size.height) / shift_size.height + 1; velx = cvCreateImage(cvSize(sX, sY), IPL_DEPTH_32F, 1); vely = cvCreateImage(cvSize(sX, sY), IPL_DEPTH_32F, 1); cvCalcOpticalFlowBM(prev, curr, block_Size, shift_size, max_range, usePrevious, velx, vely); IplImage *result = cvLoadImage("img/curr.bmp", 1); double dx, dy; CvPoint p1, p2; int threshold = 2; // Draw OpticalFlow Vector for (int y = 0; y < sY; y++) { for (int x = 0; x < sX; x++) { dx = cvGetReal2D(velx, y, x); dy = cvGetReal2D(vely, y, x); if (sqrt(dx * dx + dy * dy) < threshold) continue; p1.x = block_Size.width + x * shift_size.width; p1.y = block_Size.height + y * shift_size.height; p2.x = cvRound(p1.x + dx); p2.y = cvRound(p1.y + dy); cvLine(result, p1, p2, CV_RGB(0, 255, 0), 1, CV_AA); } } cvNamedWindow("velx"); cvShowImage("velx", velx); cvNamedWindow("vely"); cvShowImage("vely", vely); cvNamedWindow("OpticalFlow Result"); cvShowImage("OpticalFlow Result", result); cvWaitKey(0); cvDestroyAllWindows(); return 0; } | cs |
입력 영상 및 결과 영상
결과 영상 (vely) (velx)