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算法(改进MeanShift)

    目录 一.CamShift 1.1 原理 二.流程 三.代码 四.总结 一.CamShift MeanShift的结果有一个问题,检测窗口的大小是固定的,而目标是一个由近到远逐渐变小的过程,固定的窗口 ...

  2. ccot 目标跟踪全称_目标跟踪--CamShift

    转载请注明出处! !! 目标跟踪--CamShift CamShift全称是ContinuouslyAdaptive Mean Shift,即连续自适应的MeanShift算法.而MeanShift算 ...

  3. opencv目标跟踪概述和人脸跟踪

    概述 opencv内部实现了一些单目标跟踪算法,可以很方便的使用. 这里说的目标跟踪不是多目标跟踪,往往是需要人工或程序给定初始目标位置. 资源及跟踪算法介绍 目前看到的比较好的opencv目标跟踪算 ...

  4. Opencv Object Tracking【使用OpenCV目标跟踪模块】

    实时目标检测如RCNN,yolo,ssd等都是可行的解决方案,但对于工业目标检测方案落地,一些嵌入式系统架构的硬件性能不能达到这样的高性能计算要求,或者当需要对特定目标进行检测识别时,这时可以采取的方 ...

  5. 计算机视觉中,目标跟踪相关算法论文总结

    目标跟踪相关算法&论文总结 作为小白,近期想看一些目标跟踪相关的内容,但又无从下手,花了几天时间,找各种资料,总结了网上大佬们写的文章.(大部分来自CSDN.知乎.微信公众号,均已注明出处) ...

  6. Opencv——目标跟踪Tracker

    Opencv--目标跟踪Tracker OpenCV有八种不同的目标追踪工具,他们都可以运用到计算机视觉领域中.本文只用了以下六种对我现有数据的测试 MIL Tracker:追踪器精确,但是失败率比较 ...

  7. 目标跟踪--CamShift

    CamShift全称是ContinuouslyAdaptive Mean Shift,即连续自适应的MeanShift算法,而MeanShift算法,首先得对MeanShift算法有个初步的了解,可以 ...

  8. 传统目标跟踪——MeanShift算法

    目录 一.均值漂移(MeanShift) 二.流程 三.代码 3.1 meanshift+固定框的代码 3.2 优化:meanshift+鼠标选择 3.3 meanshift+自己实现函数 四.补充知 ...

  9. 单目标跟踪--KCF算法(核化相关滤波算法)Python实现(超详细)

    Tracking-KCF Algorithm 注:本文涉及的算法的代码实践已上传至GitHub,恳求大佬们指点!^ _ ^ 1. 目标检测跟踪与算法背景概述 ​ 目标跟踪任务在许多的计算机视觉系统中都 ...

最新文章

  1. mfc 静态框接收tab焦点_目标检测中焦点损失的入门指南
  2. springboot+thymeleaf+jpa博客多级评论展示案例
  3. 2020年中国智能客服行业研究报告
  4. CSS3弹性盒模型布局模块介绍
  5. 我的世界服务器显示玩家坐标,我的世界手游版怎么显示玩家坐标
  6. 常用的排序算法总结(一)
  7. class 原生js获取父元素_JS获取节点的兄弟,父级,子级元素的方法
  8. PyTorch:tensor-张量维度操作(拼接、维度扩展、压缩、转置、重复……)
  9. ckc交易什么意思_在期货交易中,所谓的期货对冲是什么意思?
  10. 软件工程经济学知识点总结
  11. 基于stm32单片机的电梯控制系统
  12. WebService专题(二)-WebService原理
  13. Unity Animator Animation详解及应用实例教程
  14. WAV音乐文件无法修改标题
  15. macOS修复系统默认文件夹显示为英文的问题
  16. DataGridView控件页脚会总行的最佳实现。
  17. (Ynoi2015) 纵使日薄西山 题解
  18. 基于Qt平台的集串口调试助手、示波器、图像显示功能于一体的上位机。
  19. 1、Vivado 安装及其破解
  20. 计算机技术与软件(初级、中级、高级)考试(软考)是什么?软考的时间安排是什么时候?

热门文章

  1. 数据库中的多表联查(四表联查)
  2. 靠一己之力造就3个首富,丁磊、刘强东、宗庆后背后的神秘女人
  3. 项目经理之新任项目经理的五项修炼
  4. 教你一招:复制不能复制的网页文字(通用篇)
  5. php-fpm启动,重启,终止操作
  6. python读取sheet_python读取excel文件中所有sheet表格
  7. 使用docker官方加速器
  8. 一个因为兴趣而走上前端开发的程序员
  9. 【语音算法】使用端点检测和百度语音识别技术实现视频的字幕生成
  10. 快速傅里叶变换FFT C语言实现 可用于嵌入式系统进行模拟采样频谱分析