原理

Camshift算法是Continuously Adaptive Mean Shift algorithm的简称。

它是一个基于MeanSift的改进算法。它首次由Gary R.Bradski等人提出和应用在人脸的跟踪上,并取得了不错的效果。因为它是利用颜色的概率信息进行的跟踪。使得它的执行效率比較高。 Camshift算法的过程由以下步骤组成:

(1)确定初始目标及其区域;

(2)计算出目标的色度(Hue)分量的直方图;

(3)利用直方图计算输入图像的反向投影图(后面做进一步的解释);

(4)利用MeanShift算法在反向投影图中迭代收索,直到其收敛或达到最大迭代次数。并保存零次矩。

(5)从第(4)步中获得收索窗体的中心位置和计算出新的窗体大小。以此为參数,进入到下一幀的目标跟踪。(即跳转到第(2)步);

代码

#include "stdafx.h"
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp" #include <iostream>
#include <ctype.h> using namespace cv;
using namespace std; Mat image; bool backprojMode = false;
bool selectObject = false;
int trackObject = 0;
bool showHist = true;
Point origin;
Rect selection(0,0,50,50); static void onMouse( int event, int x, int y, int, void* )
{
switch( event )
{
case CV_EVENT_LBUTTONDOWN:
origin = Point(x,y);
selection = Rect(x,y,0,0);
selectObject = true;
break;
case CV_EVENT_LBUTTONUP:
selectObject = false;
if( selection.width > 0 && selection.height > 0 )
trackObject = -1;
break;
}
if( selectObject )
{
selection.x = MIN(x, origin.x);
selection.y = MIN(y, origin.y);
selection.width = std::abs(x - origin.x);
selection.height = std::abs(y - origin.y);
}
} int main( int argc, const char** argv )
{
cv::VideoCapture capture(0);
capture.set( CV_CAP_PROP_FRAME_WIDTH,640);
capture.set( CV_CAP_PROP_FRAME_HEIGHT,480 );
if(!capture.isOpened())
return -1;
double rate = capture.get(CV_CAP_PROP_FPS); //获取帧率
int delay = 1000 / rate; //计算帧间延迟;
Mat frame,image,hsv,mask,hue; namedWindow("test",CV_WINDOW_AUTOSIZE);
setMouseCallback("test",onMouse,0);
while (1)
{
capture>>frame;
if(trackObject == -1){ //设置完检測的对象后開始跟踪
frame.copyTo(image);
cv::cvtColor(image,hsv,CV_RGB2HSV);
cv::inRange(hsv,Scalar(0,130,50),Scalar(180,256,256),mask); //去掉低饱和度的点
vector<cv::Mat> v;
cv::split(hsv,v); //hsv的三个通道分开
hue = v[1];
cv::Mat ROI = hue(selection); //选择感兴趣的区域
cv::Mat maskROI = mask(selection); cv::MatND hist;
int histsize[1];
histsize[0]= 16; float hranges[2];
hranges[0] = 0;
hranges[1] = 180; const float *ranges[1];
ranges[0] = hranges;
cv::calcHist(&ROI,1,0,maskROI,hist,1,histsize,ranges);//感兴趣区域的直方图。从參数太多
cv::normalize(hist,hist,0,180,CV_MINMAX); //对直方图进行归一化处理; cv::Mat backpro;
cv::calcBackProject(&hue,1,0,hist,backpro,ranges); //对h通道的进行反投影放入backpro中
backpro &= mask; cv::RotatedRect trackBox = cv::CamShift(backpro,selection,
TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER,10,1));//使用均值秒一算法找出RECT;
cv::ellipse(frame,trackBox,cv::Scalar(0,0,255),2,CV_AA);
}
cv::imshow("test",frame);
if(waitKey(30) >= 0)
break;
}
capture.release();
return 0;
}

效果


用摄像头获取视频

直接读取视频

总结:

效果不是太好。可能是没有预处理或者參数设置的不好。
刚開始学习的人。期待大婶知道!


用Camshift算法对指定目标进行跟踪的更多相关文章

  1. Opencv目标跟踪—CamShift算法

    CamShift算法全称是"Continuously Adaptive Mean-Shift"(连续的自适应MeanShift算法),是对MeanShift算法的改进算法,可以在跟 ...

  2. 44 dlib鼠标指定目标跟踪

    dlib提供了dlib.correlation_tracker()类用于跟踪目标.官方文档入口:http://dlib.net/python/index.html#dlib.correlation_t ...

  3. CamShift算法

    拟采用的方法,CamShift算法,即"Continuously Apative Mean-Shift"算法,是一种运动跟踪算法.它主要通过视频图像中运动物体的颜色信息来达到跟踪的 ...

  4. CVPR 2020几篇论文内容点评:目标检测跟踪,人脸表情识别,姿态估计,实例分割等

    CVPR 2020几篇论文内容点评:目标检测跟踪,人脸表情识别,姿态估计,实例分割等 CVPR 2020中选论文放榜后,最新开源项目合集也来了. 本届CPVR共接收6656篇论文,中选1470篇,&q ...

  5. 吴恩达机器学习笔记47-K均值算法的优化目标、随机初始化与聚类数量的选择(Optimization Objective & Random Initialization & Choosing the Number of Clusters of K-Means Algorithm)

    一.K均值算法的优化目标 K-均值最小化问题,是要最小化所有的数据点与其所关联的聚类中心点之间的距离之和,因此 K-均值的代价函数(又称畸变函数 Distortion function)为: 其中

  6. sqlbulkcopy 使用DataTable作为数据源的数据类型问题--来自数据源的String类型的给定值不能转换为指定目标列的类型 uniqueidentifier

    今天做批量插入的时候,SQLSERVER总是报错,错误提示“来自数据源的String类型的给定值不能转换为指定目标列的类型 uniqueidentifier”. 首先核对了一下定义的dataTable ...

  7. SqlBulkCopy批量插入数据 显示 来自数据源的 String 类型的给定值不能转换为指定目标列的类型 smalldatetime。错误

    因为需要大量插入数据,linq ef无法达到速度的要求,因此把模型转换成SQL ,使用SqlBulkCopy快速插入.但是去提示 来自数据源的 String 类型的给定值不能转换为指定目标列的类型 s ...

  8. 2.3 LINQ查询表达式中 使用select子句 指定目标数据

    本篇讲解LINQ查询的三种形式: 查询对象 自定义查询对象某个属性 查询匿名类型结果 [1.查询结果返回集合元素] 在LINQ查询中,select子句和from子句都是必备子句.LINQ查询表达式必须 ...

  9. Saltstack_使用指南06_远程执行-指定目标

    1. 主机规划 Targeting Minions文档 https://docs.saltstack.com/en/latest/contents.html 另请参见:自动化运维神器之saltstac ...

随机推荐

  1. SPFA ----模板 O(kE) (k一般不超过2)

    原理:若一个点入队的次数超过顶点数V,则存在负环: #include "bits/stdc++.h" using namespace std; ; struct Edge { in ...

  2. RabbitMQ的应用场景以及基本原理介绍(转)

    1.背景 RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现. 2.应用场景 2.1异步处理 场景说明:用户注册后,需要发注册邮件和注册短信, ...

  3. BZOJ 4820 [Sdoi2017]硬币游戏 ——期望DP 高斯消元

    做法太神了,理解不了. 自己想到的是建出AC自动机然后建出矩阵然后求逆计算,感觉可以过$40%$ 用一个状态$N$表示任意一个位置没有匹配成功的概率和. 每种匹配不成功的情况都是等价的. 然后我们强制 ...

  4. Element 'plugin' cannot have character [children], because the type's content type is element-only

    原因是你复制的时候,带了一些特殊符号. 解决方案: 将那一串代码复制到notpad++ 或者文本上面,再复制到你的编译器里面,就可以解决问题了

  5. 配置vscode使它能够在自定义扩展名当中支持emment语法

    在.vue文件当中默认是不支持emment的,需要在vscode设置当中设置 "emmet.syntaxProfiles": { "vue-html": &qu ...

  6. 理解 Glance

    OpenStack 由 Glance 提供 Image 服务. 理解 Image 要理解 Image Service 先得搞清楚什么是 Image 以及为什么要用 Image? 在传统 IT 环境下, ...

  7. 【NOIP2016练习】T1 挖金矿(二分答案)

    题意: 思路:二分答案A 合法的答案 sigma(s[i][xi])/sigma(xi)>=a i<=m sigma(s[i][xi]-a*xi)>=0 对于每个i找到xi使s[i] ...

  8. 标准C程序设计七---54

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  9. Struts+ibatis-学习总结一

    1查询并返回list 别名映射->实体类:resultClass <select id=" selectAll" resultClass="AppLog&qu ...

  10. react-native 判断是不是IPhone X

    import { Platform, Dimensions } from 'react-native'; // iPhoneX const X_WIDTH = 375; const X_HEIGHT ...