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实现检测和追踪车辆
  • opencv+arduino实现物体点追踪效果
  • Opencv光流运动物体追踪详解
(0)

相关推荐

  • opencv+arduino实现物体点追踪效果

    本文所要实现的结果是:通过在摄像头中选择一个追踪点,通过pc控制摄像头的舵机,使这一点始终在图像的中心. 要点:使用光流法在舵机旋转的同时进行追踪,若该点运动,则摄像头跟踪联动. #include<opencv2\opencv.hpp> #include<opencv\cv.h> #include<opencv\highgui.h> #include<math.h> #include<Windows.h> #include<string.h

  • Opencv光流运动物体追踪详解

    光流的概念是由一个叫Gibson的哥们在1950年提出来的.它描述是空间运动物体在观察成像平面上的像素运动的瞬时速度,利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法.那么所说的光流到底是什么? 简单来说,上图表现的就是光流,光流描述的是图像上每个像素点的灰度的位置(速度)变化情况,光流的研究是利用图像序列中的像素强度数据的时域变化和相关性来确定各自像素位置的"运动".研究光流场的目的就是为了从

  • 使用OpenCV实现检测和追踪车辆

    本文实例为大家分享了OpenCV实现检测和追踪车辆的具体代码,供大家参考,具体内容如下 完整源码GitHub 使用高斯混合模型(BackgroundSubtractorMOG2)对背景建模,提取出前景 使用中值滤波去掉椒盐噪声,再闭运算和开运算填充空洞 使用cvBlob库追踪车辆,我稍微修改了cvBlob源码来通过编译 由于要对背景建模,这个方法要求背景是静止的 另外不同车辆白色区域不能连通,否则会认为是同一物体 void processVideo(char* videoFilename) {

  • Opencv基于CamShift算法实现目标跟踪

    CamShift算法全称是"Continuously Adaptive Mean-Shift"(连续的自适应MeanShift算法),是对MeanShift算法的改进算法,可以在跟踪的过程中随着目标大小的变化实时调整搜索窗口大小,对于视频序列中的每一帧还是采用MeanShift来寻找最优迭代结果,至于如何实现自动调整窗口大小的,可以查到的论述较少,我的理解是通过对MeanShift算法中零阶矩的判断实现的. 在MeanShift算法中寻找搜索窗口的质心用到窗口的零阶矩M00和一阶矩M1

  • openCV中meanshift算法查找目标的实现

    目录 一.简介 二.实现过程 1.设定感兴趣的区域 2.获取脸部直方图并做归一化 3.反向投影,用meanshift查找目标 三.其他实验结果 四.部分原理补充 五.完整代码 一.简介 图像直方图的反向投影是一个概率分布图,表示一个指定图像片段出现在特定位置的概率.当我们已知图像中某个物体的大体位置时,可以通过概率分布图找到物体在另一张图像中的准确位置.我们可以设定一个初始位置,在其周围反复移动来提高局部匹配概率,从而找到物体的准确位置,这个实现过程叫做均值平移算法. 二.实现过程 因为人物的面

  • OpenCV基于ORB算法实现角点检测

    本文实例为大家分享了OpenCV基于ORB算法实现角点检测的具体代码,供大家参考,具体内容如下 ORB算法是FAST算法和BRIEF算法的结合,ORB可以用来对图像中的关键点快速创建特征向量,并用这些特征向量来识别图像中的对象. 实例化ORB orb = cv.ORB_create(nfeatures) 参数: nfeatures:特征点的最大数量 利用orb.detectAndCompute()检测关键点并计算 kp, des = orb.detectAndCompute(gray, None

  • 基于OpenCV目标跟踪实现人员计数器

    目录 1.了解对象检测与对象跟踪 2.结合对象检测和对象跟踪 3.项目结构 4.结合对象跟踪算法 5.创建可追踪对象 6.使用OpenCV+Python实现我们的人员计数器 7.完整代码 people_counter.py centroidtracker.py trackableobject.py 8.运行结果 9.改进我们的人员计数器应用程序 BONUS 在本教程中,您将学习如何使用 OpenCV 和 Python 构建人员计数器.使用 OpenCV,我们将实时计算进或出百货商店的人数. 在今

  • Python使用OPENCV的目标跟踪算法实现自动视频标注效果

    先上效果 1.首先,要使用opencv的目标跟踪算法,必须要有opencv环境 使用:opencv==4.4.0 和 opencv-contrib-python==4.4.0.46,lxml   这三个环境包. 也可以使用以下方法进行下载 : pip install opencv-python==4.4.0 pip install opencv-contrib-python==4.4.0.4 pip install lxml 2.使用方法: (1):英文状态下的 "s" 是进行标注 (

  • 基于OpenCV4.2实现单目标跟踪

    目录 1.什么是目标跟踪 2.跟踪与检测 3.使用OpenCV4实现对象跟踪 3.1使用OpenCV4实现对象跟踪C++代码 3.2使用OpenCV4实现对象跟踪Python代码 4.跟踪算法解析 4.1BOOSTINGTracker 4.2MILTracker 4.3KCFTracker 4.4TLDTracker 4.5MEDIANFLOWTracker 4.6GOTURNtracker 4.7MOSSEtracker 4.8CSRTtracker 在本教程中,我们将学习使用OpenCV跟踪

  • opencv3/C++基于颜色的目标跟踪方式

    inRange函数 void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst); src:输入图像: lowerb:下边界数组,阈值下限: upperb:上边界数组,阈值上限: dst:输出图像: 颜色范围如图: 示例: 捕获摄像头中的黄色方块 #include<opencv2/opencv.hpp> using namespace cv; int main() { VideoCaptu

  • python+opencv实现目标跟踪过程

    目录 python opencv实现目标跟踪 这里根据官网示例写了一个追踪器类 python opencv实现目标跟踪 python-opencv3.0新增了一些比较有用的追踪器算法 这里根据官网示例写了一个追踪器类 程序只能运行在安装有opencv3.0以上版本和对应的contrib模块的python解释器 #encoding=utf-8 import cv2 from items import MessageItem import time import numpy as np ''' 监视

  • Python+OpenCV目标跟踪实现基本的运动检测

    目标跟踪是对摄像头视频中的移动目标进行定位的过程,有着非常广泛的应用.实时目标跟踪是许多计算机视觉应用的重要任务,如监控.基于感知的用户界面.增强现实.基于对象的视频压缩以及辅助驾驶等. 有很多实现视频目标跟踪的方法,当跟踪所有移动目标时,帧之间的差异会变的有用:当跟踪视频中移动的手时,基于皮肤颜色的均值漂移方法是最好的解决方案:当知道跟踪对象的一方面时,模板匹配是不错的技术. 本文代码是做一个基本的运动检测 考虑的是"背景帧"与其它帧之间的差异 这种方法检测结果还是挺不错的,但是需要

  • 详解基于Facecognition+Opencv快速搭建人脸识别及跟踪应用

    人脸识别技术已经相当成熟,面对满大街的人脸识别应用,像单位门禁.刷脸打卡.App解锁.刷脸支付.口罩检测........ 作为一个图像处理的爱好者,怎能放过人脸识别这一环呢!调研开搞,发现了超实用的Facecognition!现在和大家分享下~~ Facecognition人脸识别原理大体可分为: 1.通过hog算子定位人脸,也可以用cnn模型,但本文没试过: 2.Dlib有专门的函数和模型,实现人脸68个特征点的定位.通过图像的几何变换(仿射.旋转.缩放),使各个特征点对齐(将眼睛.嘴等部位移

随机推荐