使用Opencv中均值漂移meanShift跟踪移动目标

Opencv均值漂移pyrMeanShiftFiltering彩色图像分割流程剖析

Opencv目标跟踪—CamShift算法


MeanShift - cv.MeanShift

Mean Shift均值漂移算法是无参密度估计理论的一种,无参密度估计不需要事先知道对象的任何先验知识,完全依靠训练数据进行估计,并且可以用于任意形状的密度估计,在某一连续点处的密度函数值可由该点邻域中的若干样本点估计得出。

Mean shift将特征空间视为先验概率密度函数,那么输入就被视为是一组满足某种概率分布的样本点,这样一来,特征空间中数据最密集的地方,对应于概率密度最大的地方,且概率密度的质心就可以被视为是概率密度函数的局部最优值,也就是要求的聚类中心。对于每一个样本点,计算以它为中心的某个范围内所有样本点的均值,作为新的中心(这就是shift既中心的移动),移动直至收敛。这样每一轮迭代,中心都会向数据更密集的地方移动,直到最后稳定收敛到样本的“质心”

【以下这个描述容易理解】

可以直观理解为:在样本空间中,任选一个点,然后以这个点为圆心,划定一个圆形的区域。在此区域内的所有点以圆心为起点,产生N个向量,然后把这些向量都相加,再以向量的终点为圆心,划定同样半径的圆形区域,执行同样操作,如此迭代,直到收敛。

python_opencv_version_demo2

python opencv version demo

Finds an object on a back projection image.

C++: int meanShift(InputArray probImage, Rect& window, TermCriteria criteria)
Python: cv2.meanShift(probImage, window, criteria) → retval, window
C: int cvMeanShift(const CvArr* prob_image, CvRect window, CvTermCriteria criteria, CvConnectedComp* comp)
Python: cv.MeanShift(prob_image, window, criteria) → comp
Parameters:
probImage – Back projection of the object histogram. See calcBackProject() for details.
window – Initial search window.
criteria – Stop criteria for the iterative search algorithm.
Returns:
Number of iterations CAMSHIFT took to converge.

以下程序实现了在一个视频中跟踪移动目标,大致步骤如下:

    • 1. 在视频播放过程中,通过鼠标框选需要跟踪的目标target
    • 2. 计算目标图像target的HSV中H、S分量的直方图targetHist
    • 3. 用targetHist反向投影计算原图像中的目标的概率分布
    • 4. 用meanShift通过迭代获取目标的新的位置window
    • 5. 以新的位置window执行步骤2

targetHist反向投影 - 解释

  • 假设你已经通过下图得到一个肤色直方图(Hue-Saturation), 旁边的直方图就是 模型直方图 ( 代表手掌的皮肤色调).你可以通过掩码操作来抓取手掌所在区域的直方图:

  • 下图是另一张手掌图(测试图像) 以及对应的整张图像的直方图:

  • 我们要做的就是使用 模型直方图 (代表手掌的皮肤色调) 来检测测试图像中的皮肤区域。以下是检测的步骤

    1. 对测试图像中的每个像素 (  ),获取色调数据并找到该色调(  )在直方图中的bin的位置。

    2. 查询 模型直方图 中对应的bin -  - 并读取该bin的数值。

    3. 将此数值储存在新的图像中(BackProjection)。 你也可以先归一化 模型直方图 ,这样测试图像的输出就可以在屏幕显示了。

    4. 通过对测试图像中的每个像素采用以上步骤, 我们得到了下面的 BackProjection 结果图:

    5. 使用统计学的语言, BackProjection 中储存的数值代表了测试图像中该像素属于皮肤区域的 概率 。比如以上图为例, 亮起的区域是皮肤区域的概率更大(事实确实如此),而更暗的区域则表示更低的概率(注意手掌内部和边缘的阴影影响了检测的精度)。

肤色直方图(Hue-Saturation)的一个简单的例子:


meanShfit均值漂移算法 - pyrMeanShiftFiltering

【注意,这里本质是一种 fitering】

meanShfit均值漂移算法是一种通用的聚类算法,它的基本原理是:对于给定的一定数量样本,任选其中一个样本,以该样本为中心点划定一个圆形区域,求取该圆形区域内样本的质心,即密度最大处的点,再以该点为中心继续执行上述迭代过程,直至最终收敛。

可以利用均值偏移算法的这个特性,实现彩色图像分割,Opencv中对应的函数是pyrMeanShiftFiltering。

这个函数严格来说并不是图像的分割,而是图像在色彩层面的平滑滤波,它可以中和色彩分布相近的颜色,平滑色彩细节,侵蚀掉面积较小的颜色区域,所以在Opencv中它的后缀是滤波“Filter”,而不是分割“segment”。先列一下这个函数,再说一下它“分割”彩色图像的实现过程。

Performs initial step of meanshift segmentation of an image.

C++: void pyrMeanShiftFiltering(InputArray src, OutputArray dst, double sp, double sr, int maxLevel=1, TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) )
Python: cv2.pyrMeanShiftFiltering(src, sp, sr[, dst[, maxLevel[, termcrit]]]) → dst
C: void cvPyrMeanShiftFiltering(const CvArr* src, CvArr* dst, double sp, double sr, int max_level=1, CvTermCriteria termcrit=cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,5,1))

第一个参数src,输入图像,8位,三通道的彩色图像,并不要求必须是RGB格式,HSV、YUV等Opencv中的彩色图像格式均可;

第二个参数dst,输出图像,跟输入src有同样的大小和数据格式;

第三个参数sp,定义的漂移物理空间半径大小;

第四个参数sr,定义的漂移色彩空间半径大小;

第五个参数maxLevel,定义金字塔的最大层数;

第六个参数termcrit,定义的漂移迭代终止条件,可以设置为迭代次数满足终止,迭代目标与中心点偏差满足终止,或者两者的结合;

pyrMeanShiftFiltering函数的执行过程是这样的:

1. 迭代空间构建:

以输入图像上src上任一点P0为圆心,建立物理空间上半径为sp,色彩空间上半径为sr的球形空间,物理空间上坐标2个—x、y,色彩空间上坐标3个—R、G、B(或HSV),构成一个5维的空间球体。【其实就是升维的思想】

其中物理空间的范围x和y是图像的长和宽,色彩空间的范围R、G、B分别是0~255。

2. 求取迭代空间的向量并移动迭代空间球体后重新计算向量,直至收敛:

在1中构建的球形空间中,求得所有点相对于中心点的色彩向量之和后,移动迭代空间的中心点到该向量的终点,并再次计算该球形空间中所有点的向量之和,如此迭代,直到在最后一个空间球体中所求得的向量和的终点就是该空间球体的中心点Pn,迭代结束。

3. 更新输出图像dst上对应的初始原点P0的色彩值为本轮迭代的终点Pn的色彩值,如此完成一个点的色彩均值漂移。

4. 对输入图像src上其他点,依次执行步骤1,、2、3,遍历完所有点位后,整个均值偏移色彩滤波完成,这里忽略对金字塔的讨论。

【貌似更高级一点,但是三通道也意味着更大的计算量,其实黑白照片能足够辨别的话,还是采用一通道的好】

到这里,meanShift均值偏移算法对彩色图像的平滑操作就完成了,为了达到分割的目的,需要借助另外一个漫水填充函数的进一步处理来实现,那就是floodFill。

但感觉这个方案不是很好。略。


CamShift - cv.CamShift

CamShift算法全称是“Continuously Adaptive Mean-Shift”(连续的自适应MeanShift算法),是对MeanShift算法的改进算法,

可以在跟踪的过程中随着目标大小的变化实时调整搜索窗口大小,

对于视频序列中的每一帧还是采用MeanShift来寻找最优迭代结果,至于如何实现自动调整窗口大小的,可以查到的论述较少,我的理解是通过对MeanShift算法中零阶矩的判断实现的。

反向投影,CamShift和MeanShift的运算都是在反向投影图像上进行的,反向投影的实现过程如下:

计算并生成目标区域的H分量的直方图,反向投影其实就是把目标图像上每一个像素点的像素值替换为当前像素值所在bin对应的直方图bin的数值。

Finds an object center, size, and orientation.

C++: RotatedRect CamShift(InputArray probImage, Rect& window, TermCriteria criteria)
Python: cv2.CamShift(probImage, window, criteria) → retval, window
C: int cvCamShift(const CvArr* prob_image, CvRect window, CvTermCriteria criteria, CvConnectedComp* comp, CvBox2D* box=NULL )

[Object Tracking] MeanShift的更多相关文章

  1. [Object Tracking] Overview of Object Tracking

    From: 目标跟踪方法的发展概述 From: 目标跟踪领域进展报告 通用目标的跟踪 经典目标跟踪方法 2010 年以前,目标跟踪领域大部分采用一些经典的跟踪方法,比如 Meanshift.Parti ...

  2. [Object Tracking] Overview of algorithms for Object Tracking

    From: https://www.zhihu.com/question/26493945 可以载入史册的知乎贴 目标跟踪之NIUBILITY的相关滤波 - 专注于分享目标跟踪中非常高效快速的相关滤波 ...

  3. Object Tracking Benchmark

    Abstract 问题: 1)evaluation is often not suffcient 2)biased for certain types of algorthms 3)datasets ...

  4. correlation filters in object tracking

    http://www.cnblogs.com/hanhuili/p/4266990.html Correlation Filter in Visual Tracking系列一:Visual Objec ...

  5. Correlation Filter in Visual Tracking系列一:Visual Object Tracking using Adaptive Correlation Filters 论文笔记

    Visual Object Tracking using Adaptive Correlation Filters 一文发表于2010的CVPR上,是笔者所知的第一篇将correlation filt ...

  6. Online Object Tracking: A Benchmark 论文笔记(转)

    转自:http://blog.csdn.net/lanbing510/article/details/40411877 有博主翻译了这篇论文:http://blog.csdn.net/roamer_n ...

  7. 论文笔记之:Fully-Convolutional Siamese Networks for Object Tracking

    gansh Fully-Convolutional Siamese Network for Object Tracking 摘要:任意目标的跟踪问题通常是根据一个物体的外观来构建表观模型.虽然也取得了 ...

  8. 论文笔记之:Spatially Supervised Recurrent Convolutional Neural Networks for Visual Object Tracking

    Spatially Supervised Recurrent Convolutional Neural Networks for Visual Object Tracking  arXiv Paper ...

  9. 基于粒子滤波的物体跟踪 Particle Filter Object Tracking

    Video来源地址 一直都觉得粒子滤波是个挺牛的东西,每次试图看文献都被复杂的数学符号搞得看不下去.一个偶然的机会发现了Rob Hess(http://web.engr.oregonstate.edu ...

随机推荐

  1. javaweb中为mysql的curd多个值的语句

    更新语句 String sql = "update student set num=?,name=?,birthday=?,score=?,password=? where id=?&quo ...

  2. HTML篇之CSS样式:<button></button>按钮变成超链接<a></a>的样式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. wordpress模板修改及函数说明

    原文:http://java-er.com/blog/wp-mb-edit/ WordPress基本模板文件 style.css : CSS(样式表)文件index.php : 主页模板archive ...

  4. 实现Qemu aarch32虚拟开发板ping www.baidu.com

    环境 Qemu: 2.8.0 开发板: vexpress-ca9 概述 如果要玩物联网,至少应该让开发板实现联网,让qemu支持联网在之前的博文中已经有介绍了,但是如果只能在自己的局域网内玩耍就太没意 ...

  5. 自定义Directive使用ngModel

    我们知道ngModel是AngularJS中默认的一个Directive,用于数据的双向绑定.通常是这样使用的: <input type="text" ng-model=&q ...

  6. java获取文件列表,并按照目录的深度及文件名的拼音的升序排列

    java实现在线浏览zip文件及文件下载 首先用java读出目录或是zip下的所有文件 1KG_20140718_HD/Readme-说明.htm:3.00KB1KG_20140718_HD/一键GH ...

  7. python 获取前一天或前N天的日期

    简单实现 import datetime # 获取前1天或N天的日期,beforeOfDay=1:前1天:beforeOfDay=N:前N天 def getdate(self,beforeOfDay) ...

  8. Revit对齐工具之多重对齐

    Revit对齐工具用来将一个或多个图元与选定图元对齐,比如建筑建筑时可以将梁.墙.柱等对齐到轴网,或者其它类似的图元的对齐,可以对齐同一类型的图元,或者不同类型族间的对齐,可以在二维视图.立面视图和三 ...

  9. jquery异步ajax与服务器通信过程中如何通过then方法链式传递多层数据

    我们在有些地方可能需要对服务器返回的参数做多步处理,或者很多复杂的操作必须等到服务器返回结果之后才会执行,那么我们可以用链式调用的then方法让这里做到更加易于扩展,也更加容易分离出各个功能模块.基本 ...

  10. SQL2012 之 创建备份计划

    打开数据库,选择 管理 → 右键维护计划→选择新建维护计划,填写计划名称,如下图: 修改维护计划参数,如下图: 工具箱->备份数据库任务,拖到计划里,如下图: 编辑“备份数据库”任务,如下图: ...