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 <stdio.h>
 
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\n", radius);
			if((width < 100) && (height < 100)){
				printf("image size is too small!!!\n");
				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\n", radius);
		if((width < 100) && (height < 100)){
			printf("image size is too small!!!\n");
			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));
        }

效果演示

 对应的效果演示如下:
                             
时间: 2024-10-16 16:48:38

opencv实现移动速度计算的相关文章

OpenCV 学习(计算图像的直方图)

OpenCV 计算图像的直方图 计算图像的直方图是图像处理领域一个非常常见的基本操作. OpenCV 中提供了 calcHist 函数来计算图像直方图.不过这个函数说实话挺难用的,研究了好久才掌握了些基本的用法. calcHist 函数 C++ 的函数原型如下: void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, SparseMat& hist, int dims, const i

opencv使用convexityDefects计算轮廓凸缺陷

引自:http://www.xuebuyuan.com/1684976.html http://blog.csdn.net/lichengyu/article/details/38392473 http://www.cnblogs.com/yemeishu/archive/2013/01/19/2867286.html谈谈NITE 2与OpenCV结合提取指尖坐标 一 概念: Convexity hull, Convexity defects 如上图所示,黑色的轮廓线为convexity hul

OpenCV——积分图计算

1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 #include "math.h" 4 5 using namespace cv; 6 using namespace std; 7 8 int main(int argc, char** argv) { 9 Mat src = imread("test.jpg",0); 10 if (src.empty()) { 11 print

【OpenCV学习】计算两幅图像的重叠区域

问题描述:已知两幅图像Image1和Image2,计算出两幅图像的重叠区域,并在Image1和Image2标识出重叠区域. 算法思想: 若两幅图像存在重叠区域,则进行图像匹配后,会得到一张完整的全景图,因而可以转换成图像匹配问题. 图像匹配问题,可以融合两幅图像,得到全景图,但无法标识出在原图像的重叠区域. 将两幅图像都理解为多边形,则其重叠区域的计算,相当于求多边形的交集. 通过多边形求交,获取重叠区域的点集,然后利用单应矩阵还原在原始图像的点集信息,从而标识出重叠区域. 算法步骤: 1.图像

(原+转)使用opencv的DFT计算卷积

转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5462665.html 参考网址: http://blog.csdn.net/lichengyu/article/details/18848281 貌似还有其他的,记不清了 convolveDFT函数是从官方文档中抄录并做了修改,因为原来的程序有问题.一是输出Mat C应声明为引用:二是其中的mulSpectrums函数的第四个参数flag值没有指定,应指定为DFT_COMPLEX_OUTPUT或是D

[opencv]利用minAreaRect计算平面矩形的旋转角度

#include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/features2d/features2d.hpp" //需要添加该头文件 #include <iostream> #include "Math.h&

OpenCV之Python学习笔记

OpenCV之Python学习笔记 直都在用Python+OpenCV做一些算法的原型.本来想留下发布一些文章的,可是整理一下就有点无奈了,都是写零散不成系统的小片段.现在看 到一本国外的新书<OpenCV Computer Vision with Python>,于是就看一遍,顺便把自己掌握的东西整合一下,写成学习笔记了.更需要的朋友参考. 阅读须知: 本文不是纯粹的译文,只是比较贴近原文的笔记:         请设法购买到出版社出版的书,支持正版. 从书名就能看出来本书是介绍在Pytho

Opencv学习(1):高斯滤波

快乐虾@http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 本文适用于opencv3.0.0, vs2013 Opencv中提供了高斯滤波函数: /** @brief Blurs an image using a Gaussian filter. The function convolves the source image with the specified Gaussian kernel. In-place filtering is support

计算两幅图像的重叠区域

http://www.cnblogs.com/dwdxdy/p/3232331.html 随笔- 87  文章- 0  评论- 81 [OpenCV学习]计算两幅图像的重叠区域 问题描述:已知两幅图像Image1和Image2,计算出两幅图像的重叠区域,并在Image1和Image2标识出重叠区域. 算法思想: 若两幅图像存在重叠区域,则进行图像匹配后,会得到一张完整的全景图,因而可以转换成图像匹配问题. 图像匹配问题,可以融合两幅图像,得到全景图,但无法标识出在原图像的重叠区域. 将两幅图像都