今天上午,结合OpenCV自带的camshitf例程,简单的对camshitf有了一个大体的认识和理解,现总结以下:html
1:关于HSVgit
H指hue(色相)、S指saturation(饱和度)、V指value(色调)。github
RGB 和 CMYK 分别是加法原色和减法原色模型,以原色组合的方式定义颜色,而 HSV 以人类更熟悉的方式封装了关于颜色的信息:“这是什么颜色?深浅如何?明暗如何?”。算法
更多内容可参考:维基百科
数组
2:关于Camshift算法的实现过程dom
Camshift的过程主要包含了3个部分:函数
Camshift的原理是根据关注区域的颜色(hue)的直方图来进行跟踪,因此Back Projection的过程从结果上来将就是获得hue的直方图,或者是颜色的几率分布的。什么叫作Back Projection? Back Projection 就是将hue直方图转换成hue(色彩)几率分布图。具体的步骤分为:
1):将原始RGB图像转换颜色空间到HSV色彩空间上
2):将hsv中的h份量提取出来的
3):计算出指定区域的hue直方图——直方图表明了不一样H份量取值出现的几率,或者说能够据此查找出H份量的大小为x时的几率或像素个数,即,获得颜色几率查找表tornado
4):Back Projection过程——将图像中每一个像素的值用其颜色出现的几率进行替换,由此获得颜色几率分布图post
1):设置初始化窗口
2):计算这个窗口的重心(xc,yc)
3):将窗口的中心移到重心上面去。(中心就是窗口的矩形两个对角线 的交叉点)
4):重复上面的2和3的步骤,知道最后窗口的位置再也不变换为止.学习
对于Camshift(Continuously Adaptive Mean-Shift)的基本原理是对视频图像的全部帧做MeanShift运行,并将上一帧的结果做为下一帧的初始化初始化窗口,如此迭代就能够进行跟踪了。
3:代码
结合OpenCV自带的camshitf例程,用代码实现camshitf算法过程:
1 //变量声明 2 Rect trackWindow; 3 RotatedRect trackBox; 4 int hsize = 16; 5 int ch[] = {0, 0}; 6 float hranges[] = {0,180}; 7 const float* phranges = hranges; 8 9 Mat image, hsv, hue, mask, hist;//image为摄像头或是用户加载的得到的图片 10 11 cvtColor(image, hsv, CV_BGR2HSV); 12 inRange(hsv, Scalar(0, smin, MIN(_vmin,_vmax)),Scalar(180, 256, MAX(_vmin, _vmax)), mask); 13 hue.create(hsv.size(), hsv.depth()); 14 mixChannels(&hsv, 1, &hue, 1, ch, 1); 15 calcHist(&hue, 1, 0, mask, hist, 1, &hsize, &phranges); 16 normalize(hist, hist, 0, 255, CV_MINMAX); 17 18 calcBackProject(&hue, 1, 0, hist, backproj, &phranges); 19 backproj &= mask; 20 RotatedRect trackBox = CamShift(backproj, trackWindow, 21 TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ));
对于该行代码:
1 inRange(hsv, Scalar(0, smin, MIN(_vmin,_vmax)),Scalar(180, 256, MAX(_vmin, _vmax)), mask);
inRange函数的功能是检查输入数组每一个元素大小是否在2个给定数值之间,能够有多通道,mask保存0通道的最小值,也就是h份量;这里利用了hsv的3个通道,比较h,0~180,s,smin~256,v,min(_vmin,_vmax),max(_vmin,_vmax)。若是3个通道都在对应的范围内,则mask对应的那个点的值全为1(0xff),不然为0(0x00).
参考资料:
目标跟踪学习笔记_1(opencv中meanshift和camshift例子的应用)
StevenMeng
2013.10.04