Opencv目标跟踪—CamShift算法
CamShift算法全称是“Continuously Adaptive Mean-Shift”(连续的自适应MeanShift算法),是对MeanShift算法的改进算法,可以在跟踪的过程中随着目标大小的变化实时调整搜索窗口大小,对于视频序列中的每一帧还是采用MeanShift来寻找最优迭代结果,至于如何实现自动调整窗口大小的,可以查到的论述较少,我的理解是通过对MeanShift算法中零阶矩的判断实现的。
在MeanShift算法中寻找搜索窗口的质心用到窗口的零阶矩M00和一阶矩M10,M01:
零阶矩是搜索窗口内所有像素的积分,即所有像素值之和,物理上的意义是计算搜索窗口的尺寸。经过目标的H分量直方图反向投影后,目标区域的搜索窗口大部分像素值归一化后应该是最大值255,如果计算出来零阶矩大于某一阈值,可以认为此时目标铺满了整个搜索窗口,有理由认为在搜索窗口之外的区域还存在目标区域,需要增大搜索窗口的尺寸;相应的,如果零阶矩小于某一阈值,则需要缩小搜索窗口的尺寸,如此一来,当目标的大小发生变化的时候,CamShift算法就可以自适应的调整目标区域进行跟踪。
以上过程中涉及到一个关键的概念——反向投影,CamShift和MeanShift的运算都是在反向投影图像上进行的,反向投影的实现过程如下:计算并生成目标区域的H分量的直方图,反向投影其实就是把目标图像上每一个像素点的像素值替换为当前像素值所在bin对应的直方图bin的数值。
Opencv中CamShfit在使用上跟MeanShift一致:
CamShift( InputArray probImage, CV_OUT CV_IN_OUT Rect& window,
TermCriteria criteria );
第一个参数probImage是反向投影图像
第二个参数window是输入和输出的搜索窗口/目标窗口,window的尺寸会自动调整
第三个参数criteria是迭代收敛终止条件
#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include "video/tracking.hpp"
#include<iostream>
using namespace cv;
using namespace std;
Mat image;
Mat rectImage;
Mat imageCopy; //绘制矩形框时用来拷贝原图的图像
bool leftButtonDownFlag=false; //左键单击后视频暂停播放的标志位
Point originalPoint; //矩形框起点
Point processPoint; //矩形框终点
Mat targetImageHSV;
int histSize=200;
float histR[]={0,255};
const float *histRange=histR;
int channels[]={0,1};
Mat dstHist;
Rect rect;
vector<Point> pt; //保存目标轨迹
void onMouse(int event,int x,int y,int flags ,void* ustc); //鼠标回调函数
int main(int argc,char*argv[])
{
VideoCapture video(argv[1]);
double fps=video.get(CV_CAP_PROP_FPS); //获取视频帧率
double pauseTime=1000/fps; //两幅画面中间间隔
namedWindow("跟踪木头人",0);
setMouseCallback("跟踪木头人",onMouse);
while(true)
{
if(!leftButtonDownFlag) //判定鼠标左键没有按下,采取播放视频,否则暂停
{
video>>image;
}
if(!image.data||waitKey(pauseTime)==27) //图像为空或Esc键按下退出播放
{
break;
}
if(originalPoint!=processPoint&&!leftButtonDownFlag)
{
Mat imageHSV;
Mat calcBackImage;
cvtColor(image,imageHSV,CV_RGB2HSV);
calcBackProject(&imageHSV,2,channels,dstHist,calcBackImage,&histRange); //反向投影
TermCriteria criteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, 0.001);
CamShift(calcBackImage, rect, criteria);
Mat imageROI=imageHSV(rect); //更新模板
targetImageHSV=imageHSV(rect);
calcHist(&imageROI, 2, channels, Mat(), dstHist, 1, &histSize, &histRange);
normalize(dstHist, dstHist, 0.0, 1.0, NORM_MINMAX); //归一化
rectangle(image, rect, Scalar(255, 0, 0),3); //目标绘制
pt.push_back(Point(rect.x+rect.width/2,rect.y+rect.height/2));
for(int i=0;i<pt.size()-1;i++)
{
line(image,pt[i],pt[i+1],Scalar(0,255,0),2.5);
}
}
imshow("跟踪木头人",image);
waitKey(100);
}
return 0;
}
//*******************************************************************//
//鼠标回调函数
void onMouse(int event,int x,int y,int flags,void *ustc)
{
if(event==CV_EVENT_LBUTTONDOWN)
{
leftButtonDownFlag=true; //标志位
originalPoint=Point(x,y); //设置左键按下点的矩形起点
processPoint=originalPoint;
}
if(event==CV_EVENT_MOUSEMOVE&&leftButtonDownFlag)
{
imageCopy=image.clone();
processPoint=Point(x,y);
if(originalPoint!=processPoint)
{
//在复制的图像上绘制矩形
rectangle(imageCopy,originalPoint,processPoint,Scalar(255,0,0),2);
}
imshow("跟踪木头人",imageCopy);
}
if(event==CV_EVENT_LBUTTONUP)
{
leftButtonDownFlag=false;
rect=Rect(originalPoint,processPoint);
rectImage=image(rect); //子图像显示
imshow("Sub Image",rectImage);
cvtColor(rectImage,targetImageHSV,CV_RGB2HSV);
imshow("targetImageHSV",targetImageHSV);
calcHist(&targetImageHSV,2,channels,Mat(),dstHist,1,&histSize,&histRange,true,false);
normalize(dstHist,dstHist,0,255,CV_MINMAX);
imshow("dstHist",dstHist);
}
}
蓝色窗口是跟踪的目标,绿色线条是目标走过的轨迹。
Opencv目标跟踪—CamShift算法的更多相关文章
- 目标跟踪--CamShift
转载请注明出处! !! http://blog.csdn.net/zhonghuan1992 目标跟踪--CamShift CamShift全称是ContinuouslyAdaptive Mean S ...
- Video Target Tracking Based on Online Learning—深度学习在目标跟踪中的应用
摘要 近年来,深度学习方法在物体跟踪领域有不少成功应用,并逐渐在性能上超越传统方法.本文先对现有基于深度学习的目标跟踪算法进行了分类梳理,后续会分篇对各个算法进行详细描述. 看上方给出的3张图片,它们 ...
- 目标跟踪之粒子滤波---Opencv实现粒子滤波算法
目标跟踪学习笔记_2(particle filter初探1) 目标跟踪学习笔记_3(particle filter初探2) 前面2篇博客已经提到当粒子数增加时会内存报错,后面又仔细查了下程序,是代码方 ...
- 用Camshift算法对指定目标进行跟踪
原理 Camshift算法是Continuously Adaptive Mean Shift algorithm的简称. 它是一个基于MeanSift的改进算法.它首次由Gary R.Bradski等 ...
- Python Opencv-contrib Camshift&kalman卡尔曼滤波&CSRT算法 目标跟踪实现
本次课题实现目标跟踪一共用到了三个算法,分别是Camshift.Kalman.CSRT,基于Python语言的Tkinter模块实现GUI与接口设计,项目一共包含三个文件: main.py: # co ...
- 目标跟踪之camshift---opencv中meanshift和camshift例子的应用
在这一节中,主要讲目标跟踪的一个重要的算法Camshift,因为它是连续自使用的meanShift,所以这2个函数opencv中都有,且都很重要.为了让大家先达到一个感性认识.这节主要是看懂和运行op ...
- TLD目标跟踪算法
1. 简介 TLD目标跟踪算法是Tracking-Learning-Detection算法的简称.这个视频跟踪算法框架由英国萨里大学的一个捷克籍博士生Zdenek Kalal提出.TLD将传统的视频跟 ...
- Video Target Tracking Based on Online Learning—TLD单目标跟踪算法详解
视频目标跟踪问题分析 视频跟踪技术的主要目的是从复杂多变的的背景环境中准确提取相关的目标特征,准确地识别出跟踪目标,并且对目标的位置和姿态等信息精确地定位,为后续目标物体行为分析提供足 ...
- 基于MeanShift的目标跟踪算法及实现
这次将介绍基于MeanShift的目标跟踪算法,首先谈谈简介,然后给出算法实现流程,最后实现了一个单目标跟踪的MeanShift算法[matlab/c两个版本] csdn贴公式比较烦,原谅我直接截图了 ...
随机推荐
- Shiro基础知识08----拦截器介绍(转)
1 拦截器介绍 Shiro使用了与Servlet一样的Filter接口进行扩展:所以如果对Filter不熟悉可以参考<Servlet3.1规范>http://www.iteye.com/b ...
- [Debug] Chrome Devtools: Elements - Console Integration
The Element Inspector in Chrome DevTools offers powerful integration with the console - learn how to ...
- libSVM介绍(二)
鉴于libSVM中的readme文件有点长,并且,都是採用英文书写,这里,我把当中重要的内容提炼出来,并给出对应的样例来说明其使用方法,大家能够直接參考我的代码来调用libSVM库. 第一部分,利用l ...
- 微信小程序开发中如何实现侧边栏的滑动效果?
原文链接:https://mp.weixin.qq.com/s/7CM18izpZqf0oc0D75IGmQ 1 概述 在手机应用的开发中侧边栏滑动是很常见的功能,当然在小程序中也不会例外,很多特效还 ...
- blob-照片转换与展示
File转java.sql.Blob(照片)Struts2 public Blob photos(File zp) { Blob photo=null; try { FileInputStream f ...
- hadoop集群安装(多机,非伪集群)
1. 创建用户 创建hadoop用户组:sudo addgroup hadoop 创建hadoop用户:sudo adduser -ingroup hadoop hadoop 为hadoop用户分配r ...
- 设置好ftp后用xftp连接提示无法打开,无法显示远程文件夹
原文:设置好ftp后用xftp连接提示无法打开,无法显示远程文件夹 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/the_victory/artic ...
- java中抽象类和空的方法体有什么区别?
public abstract void test();抽象方法public void test(){};方法体为空这两个有什么区别? public abstract void test(); 抽象方 ...
- Double prefix overrides to provide 16-bit operand size in a 32/64 operating mode
A processor supports an operating mode in which the default address size is greater than 32 bits and ...
- [React] Use Jest's Snapshot Testing Feature
Often when testing, you use the actual result to create your assertion and have to manually update i ...