OpenCV各模块函数使用实例(10)--运动分析和目标跟踪(Motion Analysis and Object Tracking)

23 篇文章 3 订阅
5 篇文章 0 订阅

        这一节的运动分析和目标跟踪是提供一些分析图片或图片序列中的固定背景和运动目标的函数。这些函数能够帮助提取出图片序列中的背景和运动目标,可用于处理视频帧,检测视频场景中的运动对象。

(1)、cv::accumulate(InputArray src, InputOutputArray dst, 

                                         InputArray mask=noArray())

图像的累加操作函数。这个函数累加src的某些像素到dst:

 函数支持多通道图像。每一个通道都单独处理。

函数cv::accumulate 可用于采集和统计静止相机场景中的背景,以及进一步分割背景和前景。

参数

src

输入图像,类型为CV_8UC(n)CV_16UC(n)CV_32FC(n) 或CV_64FC(n)其中n 为正整数。

dst

累加图像,与输入图像有相同的通道数,深度为CV_32F 或 CV_64F。

mask

可选的操作屏蔽。

参见

accumulateSquareaccumulateProductaccumulateWeighted

(2)、cv::accumulateProduct (InputArray src1, InputArray src2, InputOutputArray dst, 

                                                InputArray mask=noArray())

加两个输入图像的像素积到累加图像。这个函数加两个图像的乘积或两个图像选定区域的乘积到累加图像dst

函数支持多通道图像。每个通道单独处理。

参数

src1

第一个输入图像,1- 或3-通道,8-位或32-位浮点类型。

src2

第二个输入图像,与src1有相同的尺寸和类型。

dst

累加图像,与输入图像有相同数量的同到,32-位或64-位浮点类型。

mask

可选的操作屏蔽。

参见

accumulateaccumulateSquareaccumulateWeighted

(3)、cv::accumulateSquare (InputArray src, InputOutputArray dst, 

                                                InputArray mask=noArray())

加原图像的平方到累加图像。这个函数加输入图像src2次幂或它的选定区域的2次幂到累加图像dst

函数支持多通道图像。每个通道单独处理。

参数

src

输入图像,有1- 或3-通道,8-位或32-位浮点类型。

dst

累加图像,与输入图像有相同的通道数,32-位或64-位浮点类型。

mask

可选的操作屏蔽。

参见

accumulateSquareaccumulateProductaccumulateWeighted

(4)、cv::accumulateWeighted (InputArray src, InputOutputArray dst,

                                                double alpha, InputArray mask=noArray())

更新连续图像流的平均值。这个函数计算输入图像src与累加图像dst的权重和,使得dst成为帧序列的连续平均值图像:

此时,alpha 用来调节更新速率(累加器有多快来“忘记”较早的图像)。这个函数支持多通道图像,每个通道单独处理。

参数

Src

输入图像,具有1- 或 3-通道,8-位或32-位浮点类型。

dst

累加图像,与输入图像有相同的通道数,32-位或64-位浮点类型。

alpha

输入图像的权重。

mask

可选的操作屏蔽。

参见

accumulateaccumulateSquareaccumulateProduct

(5)、cv::createHanningWindow (OutputArray dst, Size winSize, int type)

这个函数计算二维汉宁窗系数。细节参考相关资料。例子如下:

//建立一个类型为CV_32F,尺寸为100x100的汉宁窗

Mat hann;

createHanningWindow(hann, Size(100, 100), CV_32F);

参数

dst

存储汉宁窗系数的目标数组。

winSize

指定的窗口尺寸(宽和高二者都必须 > 1)。

type

建立的数组类型。

(6)、cv::phaseCorrelate (InputArray src1, InputArray src2, 

                                                InputArray window=noArray(), double *response=0)

        这个函数用于检测发生在两个图像之间的平移。这个操作利用傅里叶变换定理检测频域上的平移。它可用于快速图像校准和运动评估。更多信息请参考相关资料。

计算所提供的两个源数组的互功率谱,如果必要,这两个源数组使用getOptimalDFTSize连接到一起。这个函数执行下列方程:

  • 首先施加汉宁窗作用于每一个图像,以删除可能的边缘效应。这个汉宁窗被缓存用以提高处理速度,直到数组尺寸改变。
  • 其次计算每一个源数组的前馈DFT:

此处是前馈DFT.

  • 然后,计算每个频域数组的互功率谱:

  • 接着,使用逆DFT转换这个互相关到时域:

  • 最后,计算峰值位置以及峰值周围的5x5权重质心,达到亚像素级精度。

  • 如果非0,响应参数作为峰值位置周围5x5质心内的r元素的和被计算。然后归一化到最大值为1,(说明有单一的峰) ,当有多个峰时,这个值较小。

参数

src1

源浮点数组(CV_32FC1 或 CV_64FC1)。

src2

源浮点数组(CV_32FC1 或 CV_64FC1)。

window

具有窗系数的浮点数组,用于减少边缘效应(可选)。

response

在峰值周围5x5质心范围内的信号功率,在0 和1之间(可选)。

返回

检测到的两数组之间的相移(亚像素级)

参见

dftgetOptimalDFTSizeidftmulSpectrums createHanningWindow

运动分析和目标跟踪(Motion Analysis and Object Tracking编程实例

        运动分析主要是使用图像累加方式检测图片系列的背景和移动的前景。通过不断地叠加过滤,不运动的背景被增强,运动的前景被削弱,然后通过对图片的阈值处理,获得运动物的位置。

1、cv::accumulate(InputArray src, InputOutputArray dst, 

                                                InputArray mask=noArray())

      cv::accumulateProduct (InputArray src1, InputArray src2, InputOutputArray dst, 

                                                InputArray mask=noArray())

      cv::accumulateSquare (InputArray src, InputOutputArray dst, 

                                                InputArray mask=noArray())

      cv::accumulateWeighted (InputArray src, InputOutputArray dst,

                                                double alpha, InputArray mask=noArray())

        求图像的累加和函数,其中包括,累加平均,乘积累加,平方累加和权重累加,分别对原图像进行指定操作后累加到累加器图像上,形成新的累加图像。

源图像,操作图像,使用accumulateWeight()函数,weight = 0.6,进行权重累加,从图中可以看出,每次累加源图的背景变淡,直至消失,说明在帧流图像中静止背景总是会自动形成,运动前景会逐渐消失。用背景与前景的差分图像可以正确地跟踪运动目标。

通过对捕捉图像进行处理:

cv::cvtColor(image,image1,CV_RGB2GRAY);//灰度变换采集图像

cv::GaussianBlur(image1, image1, Size(5,5), 1.5, 1.5);//高斯滤波

cv::absdiff(image1,imageBackground,imageFront);//差分图像与背景,获得前景图像(运动部分)

imageBackground.convertTo(imageBackground,CV_32FC1);  //扩展至32位做运算

cv::accumulateWeighted(image1,imageBackground,accweight,imageFront);//权重累加

imageBackground.convertTo(imageBackground,CV_8UC1);  //转换回8

cv::threshold(imageFront,imageFront,0,255,CV_THRESH_OTSU);  //阈值分割  

//开运算和膨胀都是降低灵敏度的算法,对于小的运动目标不敏感

cv::morphologyEx(imageFront, imageFront, CV_MOP_OPEN, element);//消除孤立的点

cv::dilate(imageFront,imageFront,element);//膨胀操作,消除孔洞

注意:前景图像的滤波处理,可能会影响到运动部分的敏感度,重处理会降低敏感度,轻处理会增加噪声。因此需要在实际使用中寻找平衡点。另外,可以使用其它图像特征来定位运动前景。

2、cv::phaseCorrelate (InputArray src1, InputArray src2, 

                                     InputArray window=noArray(), double *response=0)

      cv::createHanningWindow (OutputArray dst, Size winSize, int type)

        图像的平行移动(平移)通过phaseCorrelate函数可以给出亚像素级精度的移动位置度量。对于精确的目标跟踪定位有一定的意义。在视频的运动目标跟踪过程中对accumulateWeight处理过后的运动前景进行phaseCorrelate计算,可以给出运动方向和距离数据。

对于视频运动图像,计算两帧之间的移动量,图像显示,110ms之间手的移动x=0.168745,y=1.58193。正数为向右上移动,负数为向左下移动。汉宁窗的使用可以减少窗口的边缘效应。

videoCap>>image;//帧图像

Mat image1, imageFrt;

cv::cvtColor(image,image1,CV_RGB2GRAY);//灰度变换采集图像

cv::GaussianBlur(image1, image1, Size(5,5), 1.5, 1.5);//高斯滤波

cv::absdiff(image1,imageBackground, imageFrt);//差分图像与背景,获得前景图像(运动部分)

cv::GaussianBlur(imageFrt, imageFrt, Size(5,5), 1.5, 1.5);//高斯滤波

imageBackground.convertTo(imageBackground,CV_32FC1);

cv::accumulateWeighted(image1,imageBackground, 0.6, imageFrt);

imageBackground.convertTo(imageBackground,CV_8UC1);  //转换回8

cv::threshold(imageFrt, imageFrt,0,255,CV_THRESH_OTSU);  //阈值分割

cv::morphologyEx(imageFrt, imageFrt, CV_MOP_OPEN, element);

cv::dilate(imageFrt,imageFrt,element);

cv::dilate(imageFrt,imageFrt,element);

if (frontImg.empty()){

    frontImg = imageFrt.clone();

    frontImg.convertTo(frontImg, CV_32FC1);

}

vector<vector<Point>> contours

vector<Vec4i> hierarchy

vector<Point> accAllcontours

cv::findContours(imageFrt,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_NONE,Point());

for(size_t i=0;i<contours.size();i++){

    for (size_t j = 0; j < contours[i].size(); j++){

        accAllcontours.push_back(contours[i].at(j));

    }

}

RotatedRect rect=cv::minAreaRect(accAllcontours); 

Point2f P[4]; 

rect.points(P); 

for(int j=0;j<=3;j++){ 

    line(image,P[j],P[(j+1)%4],Scalar(0,255,255),2); 

}        

//

imageFrt.convertTo(imageFrt, CV_32FC1);

Point2f shftP;

if (hanning){

    shftP = cv::phaseCorrelate(imageFrt, frontImg, hanningwin);

}else{

    shftP = cv::phaseCorrelate(imageFrt, frontImg);

}

frontImg = imageFrt.clone();

//显示数据

ostringstream intv;

intv << val;

intv << " x = ";

intv << shftP.x;

intv << " y = ";

intv << shftP.y;

//

cv::putText(image, intv.str(), Point(20,20), 1, 1, Scalar(255,0,255), 2);

注意:hanningwin是初始化时生成的,accAllcontours是为了计算运动目标的总外围矩形而生成的。frontImg = imageFrt.clone();则是保留当前前景图像,便于与下一帧进行比较(初始为背景图)。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要下载OpenCV学习中的运动目标(前景)检测源码,可以按照以下步骤进行。 首先,访问OpenCV的官方网站(https://opencv.org/)或GitHub的OpenCV仓库(https://github.com/opencv/opencv),找到源代码的下载选项。 在官方网站上,可以选择下载最新版本的OpenCV,或者根据特定版本的需求进行选择。在GitHub上,可以浏览仓库的不同分支和版本标签,并选择下载相应的源代码。 一旦选择了合适的源码下载选项,点击下载按钮进行下载。下载完成后,将源代码文件解压缩至本地目录。 接下来,在下载的源代码文件夹中,找到与运动目标检测相关的示例代码或项目。这些示例代码通常位于“samples”或“examples”文件夹中,可以根据名称或说明找到与运动目标检测相关的示例。 打开示例代码文件,使用合适的集成开发环境(IDE)或文本编辑器加载源代码。确保已正确配置编译环境和OpenCV库文件。 阅读示例代码的注释和文档,理解实现运动目标检测的算法和方法。 对于初学者,建议阅读和运行示例代码,以更好地理解和学习运动目标检测的概念和实践。根据需要,可以根据示例代码进行修改和调整,以满足特定的需求。 总之,要下载OpenCV学习中的运动目标(前景)检测源码,首先选择合适的源代码下载选项,然后解压缩源代码文件夹,找到与运动目标检测相关的示例代码或项目,最后阅读和运行示例代码以学习和实践运动目标检测。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愚鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值