opencv3中camshift详解(二)camshift原理介绍

一、meanshift原理介绍

想要理解camshift算法,需要先理解meanshift。opencv中CamShift函数的程序实际上只是比MeanShift程序多出一个调整搜索框大小的步骤。
meanshfit算法又称均值漂移算法,是一个迭代的步骤,即先算出当前点的偏移均值,将该点移动到此偏移均值,然后以此为新的起始点,继续移动,直到满足最终的条件。可以看下图,比较直观:
图片来自简单易学的机器学习算法——Mean Shift聚类算法
1.在ROI内计算偏移均值

2.移动ROI圆心点到偏移均值点处(重心)

3.重复上述的过程(计算新的偏移均值,移动)

经过几次迭代,可以使圆的中心和小球密度最大的点(重心)重合,不再移动。
meanshift应用在实际目标追踪上的话和上图过程有一些区别,但是原理是类似的。图像的像素点是横平竖直排列的,像素点之间的距离相同,上图的小球是疏密相间彼此间的距离不一样;图像的像素点各自的值也不一样,上图的小球各自的“重量”默认相等。原理上都是搜索圆心向“重心”移动,在上图中搜索圆的圆心是向小球最多最密的地方移动,在图像中,将图像看成二维的重量分布不均匀的薄木板,搜索圆心向薄木板的“重心”移动。
在opencv3中camshift详解(一)中,已经知道是求得反向投影之后再进行camshift追踪,反向投影是以直方图为参照产生的概率分布图,以人脸追踪为例,越可能是人脸的地方,像素的值就越大越“重”,此时对反向投影使用meanshift,搜索框会向图像的“重心”移动,可以预见搜索框最终会停留在人脸可能性最大的地方。输入下一帧图像,重复上述过程,如果人脸位置改变,则反向投影也会改变,搜索框会移动至新的“重心”,搜索框显示在连续图像上就达成了“人脸追踪”效果。
可以看出追踪效果的质量依赖于反向投影的准确性,如果追踪目标和背景的色调(Hue)相近,则会影响到反向投影,造成追踪效果不佳。

二、Bradski论文中的camshift原理介绍

camshift方法的提出是在Bradski的论文《Computer Vision Face Tracking For Use in a Perceptual User Interface
》中,这篇论文发表于1998年,年代已经久远了,论文的实现专门用来追踪人脸,因此与opencv中的camshiftdemo程序的流程相比有所差异,主要是在搜索框的初始化和大小变化上。理解这篇论文对接下来理解CamShift函数源码会有所帮助。论文中CamShift流程在第5页。由第4第5步可以发现camshift算法是以meanshift算法为基础,唯一多出来的步骤是根据0阶矩计算下一帧图像的搜索框的大小。meanshift算法中搜索框是大小不变的,而视频中的目标会因为远近而变化大小,目标过大时,搜索框无法包含目标全貌,出现追踪丢失的情况,而目标过小时,框内不属于目标的像素会造成干扰。

下面是我对文章中几个点的思考。

搜索框的初始化

1)搜索框初始大小如何确定?
论文中的因为camshift的搜索框是adaptive的,所以对初始的搜索框的大小没有特定要求。只需要是面积大于1,为了方便确定中心长和宽最好是奇数,结合这两个条件可以确定初始搜索框的最小面积是3(长为3宽为1),当然选择其他满足条件的搜索框也可以。在camshiftdemo中可以尝试框选一个比较小的搜索框,会发现搜索框确实会自适应,“生长”成较大的搜索框。


2)搜索框初始位置如何确定?
论文的方法就比较简单粗暴,计算整个图像的颜色概率分布,然后计算质心,质心位置就是搜索框的中心位置,camshiftdemo中需要手工框选。个人想法是论文中camshift专门用来人脸追踪,因此会事先存储人脸的颜色直方图用于计算图像的颜色概率分布,而opencv中的camshiftdemo不仅仅应用于人脸追踪,不可能只使用一套人脸的直方图去追踪杯子/书/足球,因此需要针对不同的目标,手动框选后实时计算颜色直方图。论文的方法优点是事前工作做足的话能够实现对人脸自动追踪,不需要人工框选,camshiftdemo的优点是适用性广,也避免了论文方法第一帧用全图算质心可能存在的误差。
论文中给出了0阶矩和质心的计算公式:一个小注意点的是此处的xy轴是以搜索框为坐标而不是以整幅图像为坐标。

搜索框的大小变化

确定了搜索框的初始位置和大小,那么下一帧图像输入之前,搜索框的大小应该如何变化呢?论文中直接给出了公式:


当然论文中也给出了公式的解释:
1)由上文的定义可以知道0阶矩(M00)是搜索框下区域所有像素值的和,0阶矩除以像素值中的最大值,就能估计出像素的个数。
" the maximum distribution value per discrete cell is 206, so we divide the zeroth moment by 206 to convert the calculated area under the search window to units of number of cells." 这段英文卡了我很久,一直没读懂是什么意思,后来才想明白,units of number of cells指的是“number of cells”这么多个units(单元、单位)。看来英语不行看论文确实费劲啊,自己做了一张图方便理解。


2)算出搜索框的二维面积之后,开平方就得到了一维长度,为了保证搜索框能够自行增长又对开平方的结果乘2就得到新的搜索框宽度s,个人认为这里乘大于1的数都可以保证“自行增长”这个属性。因为人脸是椭圆形,搜索框的长度=1.2s。
3)搜索框会无限增长吗?
最开始我有点担心,因为公式中的
2其实是一个很大的数据,思考了下我认为并不会,搜索框会在前期迅速增长,因为正好处在人脸区域,基本都是值为255的像素,0阶矩的值会随着搜索框的增大而增大,而等到搜索框包含全部人脸,开始包含无关像素后,因为人脸像素以外的值都是1,2这些很小的值,0阶矩会趋近于一个稳定的值,搜索窗的宽度也就不再增长了。

旋转角度计算

论文直接给出了计算头旋转角度的公式:


并且又给出了利用二阶矩计算概率分布“斑点”的主轴长度和短轴长度的计算公式。

论文中并没有提及角度和长轴短轴这几个公式的原理,也没有解释什么是“长轴短轴”,只是说角度、长轴、短轴可以表示出头部的转动和长宽,从效果图可以看出确实实现了,论文并没有把这些带有二阶矩的结果应用于下一帧搜索框的大小变化,只是像上文那样使用零阶矩确定下一个搜索框的大小,如果阅读过opencv的CamShfit()函数源码的话,会发现源码中是利用求得的角度和长宽计算下一帧搜索框的变化的,这是我发现的opencv源码和论文实现的最大的不同点,这部分会在第三篇文章里写下我的一些疑惑和思考。
如果只需要实现的话,那么直接使用上述三个公式就行,本文接下来的部分就不需要看了,如果对公式背后的原理感兴趣的话可以接着看,不过与其说是图像处理问题,更像是统计和几何等数学问题,还掺杂转动惯量这种物理问题,我看的也是比较迷茫,希望有大神给点指点吧。

三、剩余问题和对问题的思考

学过概率论的可能会了解一阶矩二阶矩这些东西,在文末参考链接[1]中,矩应用于二维图像上就可以得到图像的统计特征,将图像看成是一个薄板物体的话,零阶矩是物体的质量,一阶矩和零阶矩可以算出物体的中心,而二阶矩是用来计算物体的方向的。在参考链接[2]的第40页和参考链接[3]的第二部分应用中,有写到“事实上,如果仅考虑阶次为2的矩集,则原始图像等同于一个具有确定的大小、方向和离心率,以图像质心为中心且具有恒定辐射率的椭圆。”
1)为什么可以看作是椭圆?
我不知道,希望有懂的可以告诉我。
2)这个椭圆,和本文第二部分末尾的长短轴有没有关系?
我认为指的是是同一个椭圆,长短轴是用二阶矩计算出来的,也是以图像质心为椭圆圆心。
3)这个椭圆能否作为搜索框显示在视频上?
我认为这个椭圆在目标追踪中覆盖了绝大多数值为255的像素点,可以作为显示的追踪框,比起横平竖直的矩形追踪框,椭圆可以显示出旋转角度的变化,更有优势。在camshiftdemo中,对求出的椭圆进行了一些处理,得到了一个旋转矩形,用旋转矩形的内接椭圆作为追踪框。
4)求出来的角度θ,是个什么东西?
最初的时候对这个θ很疑惑,一些离散的像素,有质心可以理解,这个图像的角度应该如何理解?一幅图像铺满了灰度值不为0的像素,图像的角度又从何说起呢?
如果把利用二阶矩把图像看作一个椭圆,这个角度就比较好理解了,就是椭圆主轴和x轴所成的角度,这个角度的范围是[-90°,90°],可以参考链接[4]学习如何判断角的正负性,我个人的理解是靠近Y轴角度增大,远离Y轴角度减小。需要注意的是链接[4]中的求角度的公式,M02和M20指的是二阶中心矩,而论文中所用公式中M02和M20是指二阶原点矩。中心矩和原点矩的差别与联系,可以查看参考链接[5],将链接[4]中求角度公式的中心矩μ02和μ20用链接[5]中原点矩替换,化简后就得到了和论文中一样的公式,过程如下图。[5]中有个中心矩μ20和原点矩关系有个小错误,应该是μ20=m20-x*m10,不过不影响理解。

[1]图像的矩,以及利用矩求图像的重心,方向
[2]基于几何代数理论的医学图像配准研究
[3]不变矩方法研究
[4]图像处理基础知识(二)—— 中心矩求主轴方向
[5]opencv学习(四十三)之图像的矩moments()

总结

终于把论文梳理了一遍,写下了自己的思考,这篇论文是我研究了一段时间CamShift()函数源码后再看的,不得不说论文和具体实践还是有很大差别,第一点是没想到源码里下一帧搜索框大小的确定和论文里的实现不一样,前者是利用到了二阶矩,后者仅仅利用零阶矩,二阶矩计算出的长短轴和角度完全没用上,第二点是论文中计算角度和长短轴公式和源码中计算角度长短轴的公式本质是一样的,但用了两种不同的形式,加上原点矩中心矩这些概念,花费了大量时间在研究数学上。其实这些公式背后的原理,在工程中没必要深究,很耗时间,会用就行,但谁还没个探索之心呢,是吧?
第三篇文章主要想写一下CamShift()的代码实现,以及最重要的下一帧搜索框的大小变化方法,又是一个巨大的工程啊,再接再厉吧。

opencv3中camshift详解(二)camshift原理介绍相关推荐

  1. C++11 并发指南四(future 详解二 std::packaged_task 介绍)

    上一讲<C++11 并发指南四(<future> 详解一 std::promise 介绍)>主要介绍了 <future> 头文件中的 std::promise 类, ...

  2. Pytorch|YOWO原理及代码详解(二)

    Pytorch|YOWO原理及代码详解(二) 本博客上接,Pytorch|YOWO原理及代码详解(一),阅前可看. 1.正式训练 if opt.evaluate:logging('evaluating ...

  3. Android面试Hash原理详解二

    Hash系列目录 Android面试Hash原理详解一 Android面试Hash原理详解二 Android面试Hash常见算法 Android面试Hash算法案例 Android面试Hash原理详解 ...

  4. DPC密度峰值聚类算法原理详解二

    DPC密度峰值聚类算法原理详解二 1.计算数据点两两之间的距离 1.使用 Numpy 模块查找两点之间的欧几里得距离: 2.使用 distance.euclidean() 函数查找两点之间的欧式距离: ...

  5. (二)Flowable中TaskServiceAPI详解

    Flowable中TaskServiceAPI详解 1.FormInfo getTaskFormModel​(String taskId) 获取特定任务任务表单的表单模型实例 参数: taskId-I ...

  6. Win7系统Visual Studio 2013配置OpenCV3.1图文详解

    Win7系统Visual Studio 2013配置OpenCV3.1图文详解 OpenCV3.1对硬件加速和移动开发的支持相对于老版本都有了较大改进,支持新的开发工具,更易于扩展,配置方式也比以前简 ...

  7. 【转】图形流水线中坐标变换详解:模型矩阵、视角矩阵、投影矩阵

    转自:图形流水线中坐标变换详解:模型矩阵.视角矩阵.投影矩阵_sherlockreal的博客-CSDN博客_视角矩阵 图形流水线中坐标变换详解:模型矩阵.视角矩阵.投影矩阵 图形流水线中坐标变换过程 ...

  8. 【转详解步进电机工作原理】

    详解步进电机工作原理[转自知乎gk-auto] 步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件.在非超载的情况下,电机的转速.停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响, ...

  9. 24.shell中list详解,定义list,获取List的总个数,获取list的某个元素值,将list的每个元素转换成以空格分隔的字符串,空格分隔的字符串转换成list,for循环list

    文章目录 前言 定义list 获取List的总个数 获取list的某个元素值 将list的每个元素转换成以空格分隔的字符串 空格分隔的字符串转换成list for循环list 总结 友情链接 前言 s ...

  10. 19. linux中权限详解,Linux权限位,读写执行权限真正含义,chmod详解

    linux中权限详解,Linux权限位,读写执行权限真正含义,chmod详解 文章目录 Linux权限位 读写执行 三种权限真正含义和作用 权限对文件的作用 权限对目录的作用 示例 chmod 使用数 ...

最新文章

  1. 数据库抽取,生成CSV文件导出,CSVUtils工具类
  2. 自定义present和dismiss的转场动画
  3. WxCountUp - 数字滚动(微信小程序插件)
  4. Linux与云计算——第二阶段 第五章:存储Storage服务器架设—分布式存储GlusterFS基础...
  5. Ubuntu基本命令
  6. vue组件实现查看大图效果
  7. 清理收藏夹中的json
  8. Android初级教程:Android中解析方式之pull解析
  9. Eucalyptus 云计算
  10. OpenGL学习(七)通过assimp库读取多种格式的模型
  11. 古人为什么除了本名还要取字号?取字号根据什么规矩呢?
  12. 王者荣耀安卓区修改荣耀战区方法 | 最低战力查询(附带视频与安装包)
  13. vue实现消息badge 标记_vue 新消息提示
  14. android 7.1 白屏,苹果iphone7手机白屏怎么回事 iphone7白屏不能关不了机的快速解决办法...
  15. 程序员如何利用技术变现?
  16. 每日新闻:联想怎么又是全球第一?
  17. 网络故障排查常见方法
  18. 光谱特征选择---随机蛙跳变量选择RF
  19. matlab simulink 车辆能耗_[Lib库 1]CoppeliaSim差分避障小车的Simulink实现
  20. 第六章 网上银行与电子支付-2

热门文章

  1. 《物联网Android程序开发案例式教程》Demo2:相对布局
  2. 高并发时代下的设计模式-GO和JAVA的对比
  3. 软件需求文档模板及说明
  4. NSTimer循环引用
  5. 中文版orgin图像数字化工具_GetData Graph Digitizer(图表数字化工具) V2.25 官方版
  6. eclipse汉化版的问题
  7. 空间曲线曲率算法c语言,第一章第四节空间曲线曲率计算公式及推导
  8. PLC控制系统设计的基本原则和主要内容
  9. CANape中使用vCDMStudio批量标定
  10. pr cpu100%_PR插件Beauty Box安装教程