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算法的更多相关文章

  1. 目标跟踪--CamShift

    转载请注明出处! !! http://blog.csdn.net/zhonghuan1992 目标跟踪--CamShift CamShift全称是ContinuouslyAdaptive Mean S ...

  2. Video Target Tracking Based on Online Learning—深度学习在目标跟踪中的应用

    摘要 近年来,深度学习方法在物体跟踪领域有不少成功应用,并逐渐在性能上超越传统方法.本文先对现有基于深度学习的目标跟踪算法进行了分类梳理,后续会分篇对各个算法进行详细描述. 看上方给出的3张图片,它们 ...

  3. 目标跟踪之粒子滤波---Opencv实现粒子滤波算法

    目标跟踪学习笔记_2(particle filter初探1) 目标跟踪学习笔记_3(particle filter初探2) 前面2篇博客已经提到当粒子数增加时会内存报错,后面又仔细查了下程序,是代码方 ...

  4. 用Camshift算法对指定目标进行跟踪

    原理 Camshift算法是Continuously Adaptive Mean Shift algorithm的简称. 它是一个基于MeanSift的改进算法.它首次由Gary R.Bradski等 ...

  5. Python Opencv-contrib Camshift&kalman卡尔曼滤波&CSRT算法 目标跟踪实现

    本次课题实现目标跟踪一共用到了三个算法,分别是Camshift.Kalman.CSRT,基于Python语言的Tkinter模块实现GUI与接口设计,项目一共包含三个文件: main.py: # co ...

  6. 目标跟踪之camshift---opencv中meanshift和camshift例子的应用

    在这一节中,主要讲目标跟踪的一个重要的算法Camshift,因为它是连续自使用的meanShift,所以这2个函数opencv中都有,且都很重要.为了让大家先达到一个感性认识.这节主要是看懂和运行op ...

  7. TLD目标跟踪算法

    1. 简介 TLD目标跟踪算法是Tracking-Learning-Detection算法的简称.这个视频跟踪算法框架由英国萨里大学的一个捷克籍博士生Zdenek Kalal提出.TLD将传统的视频跟 ...

  8. Video Target Tracking Based on Online Learning—TLD单目标跟踪算法详解

    视频目标跟踪问题分析         视频跟踪技术的主要目的是从复杂多变的的背景环境中准确提取相关的目标特征,准确地识别出跟踪目标,并且对目标的位置和姿态等信息精确地定位,为后续目标物体行为分析提供足 ...

  9. 基于MeanShift的目标跟踪算法及实现

    这次将介绍基于MeanShift的目标跟踪算法,首先谈谈简介,然后给出算法实现流程,最后实现了一个单目标跟踪的MeanShift算法[matlab/c两个版本] csdn贴公式比较烦,原谅我直接截图了 ...

随机推荐

  1. 主定理(Master Theorem)与时间复杂度

    1. 问题 Karatsuba 大整数的快速乘积算法的运行时间(时间复杂度的递推关系式)为 T(n)=O(n)+4⋅T(n/2),求其最终的时间复杂度. 2. 主定理的内容 3. 分析 所以根据主定理 ...

  2. linux cmd cp -a

    cp -a 在保留原文件属性的前提下复制文件    cp -r dirname destdir   复制目录后其文件属性会发生变化 想要使得复制之后的目录和原目录完全一样,可以使用cp -a dirn ...

  3. P2P平台的"我要借款"功能,是否需要上传借款人的相关资料

     P2P平台的前端系统,一般都会有"我要借款"这个功能.有的平台,非常重视这个功能, 把它作为主要菜单的其中一项.有的把它看得相对次要,放在顶部Top栏中. 毕竟P2P平台,其实主 ...

  4. 新浪sae上安装原生wordpress4.1

    1. 加入/改动wp-config.php文件 <?php /** * WordPress 基础配置文件. * * 本文件包括下面配置选项: MySQL 设置.数据库表名前缀. * 密匙.Wor ...

  5. ios sqlite数据库操作

    @interface MyViewController () { // 数据库实例,代表着整个数据库 sqlite3 *_db; } @end @implementation MyViewContro ...

  6. ldd 查看程序/动态库 的依赖

    今天在帮同事查看一个问题时, 需要用到ldd, 于是就顺便看了一下ldd的实现. 好在ldd本身只是一个脚本, 而不是executable, 可以直接查看实现的代码. 根据注释: 21 # This ...

  7. python画最最简单的折线图

    # encoding=utf-8import matplotlib.pyplot as pltfrom pylab import * #支持中文mpl.rcParams['font.sans-seri ...

  8. 致ITFriend用户

    ) 全权处理,相关问题请和他沟通. 祝大家中秋节快乐,一家团团圆圆. 小雷FansUnion   湖北 武汉   2014年9月7日 --------------------------------- ...

  9. 【39.66%】【codeforces 740C】Alyona and mex

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  10. Vivado 2017.2 SDK 生成FSBL时存在的bug

    SDK 2017.1/.2 - ld.exe: cannot find -lrsa When importing a new HDF file into the SDK or after a clea ...