今天上午,結合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