Opencv移動速度計算の実現


概要
      opencv  phaseCorrelate   video                           。

phaseCorrelate
  Point2d phaseCorrelate(InputArray src1, InputArray src2, InputArray window=noArray())
    src1:   video  ;
    src2:  video  ;
    window:         ,        (  )。
       Point2d:       ,x  src2   src1 X       ,y  src2   src1 Y       ;

実例説明
具体コード
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include 
 
using namespace cv;
 
int main(int argc, char* argv[])
{
    VideoCapture video(argv[1]);
    Mat frame, curr, prev, curr64f, prev64f, hann;
	int key = 0;
	Mat imageROI;
	CvFont font;    
	double hScale=1;   
	double vScale=1;    
	int lineWidth=1;
	char showMsg[20];
 
	cvInitFont(&font,  CV_FONT_HERSHEY_PLAIN|CV_FONT_ITALIC, hScale,vScale,0,lineWidth);
    do
    {
        video >> frame;
        cvtColor(frame, curr, COLOR_RGB2GRAY);
 
        if(prev.empty()){
            prev = curr.clone();
            createHanningWindow(hann, curr.size(), CV_64F);
        }
 
		if(curr.empty()){
			break;	
		}
        prev.convertTo(prev64f, CV_64F);
        curr.convertTo(curr64f, CV_64F);
 
        Point2d shift = phaseCorrelate(prev64f, curr64f, hann);
        double radius = cv::sqrt(shift.x*shift.x + shift.y*shift.y);
 
        if(radius > 5){
			int width = curr.cols;
			int height = curr.rows;
			Point center(50, 40);
			printf("radius:%lf
"
, radius); if((width < 100) && (height < 100)){ printf("image size is too small!!!
"
); break; } imageROI = frame(cv::Rect((width - 100), 5, 95, 100)); IplImage img = imageROI; cvZero(&img); circle(imageROI, center, (int)radius, cv::Scalar(0, 255, 0), 1, CV_AA); line(imageROI, center, Point(center.x + (int)shift.x, center.y + (int)shift.y), cv::Scalar(0, 255, 0), 1, CV_AA); sprintf(showMsg, "x:%d", -(int)shift.x); cvPutText(&img, showMsg ,cvPoint(10,85),&font,CV_RGB(255,0,0)); sprintf(showMsg, "y:%d", -(int)shift.y); cvPutText(&img, showMsg ,cvPoint(10,97),&font,CV_RGB(255,0,0));   }   imshow("phase shift", frame); key = waitKey(20); if(key == 'q'){ break; }   prev = curr.clone(); } while((char)key != 27);   return 0; }

コードの説明
  1、   cvInitFont       ,        ,         video  ,            ,     CV_64F,
    phaseCorrelate     ,   sqrt           shift    radius,  radius  5,         。    
    ,          ,                 。
cvInitFont(&font,  CV_FONT_HERSHEY_PLAIN|CV_FONT_ITALIC, hScale,vScale,0,lineWidth);
    do
    {
        video >> frame;
        cvtColor(frame, curr, COLOR_RGB2GRAY);
 
        if(prev.empty()){
            prev = curr.clone();
            createHanningWindow(hann, curr.size(), CV_64F);
        }
 
		if(curr.empty()){
			break;	
		}
        prev.convertTo(prev64f, CV_64F);
        curr.convertTo(curr64f, CV_64F);
 
        Point2d shift = phaseCorrelate(prev64f, curr64f, hann);
        double radius = cv::sqrt(shift.x*shift.x + shift.y*shift.y);
 
        if(radius > 5){
            ............
        }
 
        imshow("phase shift", frame);
        key = waitKey(20);
		if(key == 'q'){
			break;
		}
 
        prev = curr.clone();
    } while((char)key != 27);
  2、  radius  5,        , imageROI   100x100   ,                shift,          ,
          ,         ,   X Y ,       。
        if(radius > 5){
		int width = curr.cols;
		int height = curr.rows;
		Point center(50, 40);
		printf("radius:%lf
"
, radius); if((width < 100) && (height < 100)){ printf("image size is too small!!!
"
); break; } imageROI = frame(cv::Rect((width - 100), 5, 95, 100)); IplImage img = imageROI; cvZero(&img); circle(imageROI, center, (int)radius, cv::Scalar(0, 255, 0), 1, CV_AA); line(imageROI, center, Point(center.x + (int)shift.x, center.y + (int)shift.y), cv::Scalar(0, 255, 0), 1, CV_AA); sprintf(showMsg, "x:%d", -(int)shift.x); cvPutText(&img, showMsg ,cvPoint(10,85),&font,CV_RGB(255,0,0)); sprintf(showMsg, "y:%d", -(int)shift.y); cvPutText(&img, showMsg ,cvPoint(10,97),&font,CV_RGB(255,0,0)); }

効果のデモ
          :