camshift演算法是continuously adaptive mean shift algorithm的簡稱。它是乙個基於meansift的改進演算法。它首次由gary r.bradski等人提出和應用在人臉的跟蹤上,並取得了不錯的效果。由於它是利用顏色的概率資訊進行的跟蹤,使得它的執行效率比較高。camshift演算法的過程由下面步驟組成:
(1)確定初始目標及其區域;
(2)計算出目標的色度(hue)分量的直方圖;
(3)利用直方圖計算輸入影象的反向投影圖(後面做進一步的解釋);
(4)利用meanshift演算法在反向投影圖中迭代收索,直到其收斂或達到最大迭代次數。並儲存零次矩;
(5)從第(4)步中獲得收索視窗的中心位置和計算出新的視窗大小,以此為引數,進入到下一幀的目標跟蹤。(即跳轉到第(2)步);
幾點說明:
1. 在輸入影象進行反向投影圖之前在hsv空間內做了乙個閥值處理,用以濾掉一些雜訊。
2. 反向投影圖則是概率分布圖,在反向投影圖中某一畫素點的值指的是這個點符合目標的概率分布的概率是多少,或者直接說其為目標影象畫素點的畫素點是多少。計算方法為:根據畫素點的畫素值查目標的直方圖,其對應畫素值的概率是多少就做為該點在反向投影圖中的值。
3. cam****演算法到底是怎樣自適應調整視窗的大小的。擴大:canshift演算法在計算視窗大小前,在meanshift算出的視窗的四個方向上增大了tolerance,即高和寬都增大了2tolerance(此值自己調整設定),這才有可能使得視窗能夠變大。縮小:在擴大的視窗內重新計算0階矩,1階矩和2階矩,利用矩的值重新計算高和寬。因此camshif演算法相當於在meanshift的結果上,再做了乙個調整,從而使得跟蹤的視窗大小能夠隨目標的大小變化。
優點:演算法的效率比較高,如果能利用多少特徵做出來的統計直方圖,我估計實驗效果會更好。
缺點:(1)只利用顏色統計做的跟蹤,在背景有相似顏色時,會出現跟蹤錯誤的情況。(2)不能做多目標跟蹤。(3)由於它只在初始位置(而不是從每個畫素點)開始迭代,所以有可能在初始位置錯了後,收斂的位置還是原位置(即跟丟了後,可能會找不回來)。
問題:**中有關於視窗大小調整,是根據直方圖來迭代求解,不知是怎麼回事?在**中沒看到實現。在此向大家請教!
下面是camshift演算法demo的**: **
#pragma package
#endif
#define cv_no_backward_compatibility
#ifndef _eic
#include "cv.h"
#include "highgui.h"
#include
#include
#endif
iplimage *image = 0, *hsv = 0, *hue = 0, *mask = 0, *backproject = 0, *histimg = 0;
cvhistogram *hist = 0;
int backproject_mode = 0;
int select_object = 0;
int track_object = 0;
int show_hist = 1;
cvpoint origin;
cvrect selection;
cvrect track_window;
cvbox2d track_box;
cvconnectedcomp track_comp;
int hdims = 16;
float hranges_arr = ;
float* hranges = hranges_arr;
int vmin = 10, vmax = 256, smin = 30;
void on_mouse( int event, int x, int y, int flags, void* param )
switch( event )
} cvscalar hsv2rgb( float hue )
, , , , , };
hue *= 0.033333333333333333333333333333333f;
sector = cvfloor(hue);
p = cvround(255*(hue - sector));
p ^= sector & 1 ? 255 : 0;
rgb[sector_data[sector][0]] = 255;
rgb[sector_data[sector][1]] = 0;
rgb[sector_data[sector][2]] = p;
return cvscalar(rgb[2], rgb[1], rgb[0],0); }
int main( int argc, char** argv )
printf( "hot keys: \n"
"\tesc - quit the program\n"
"\tc - stop the tracking\n"
"\tb - switch to/from backprojection view\n"
"\th - show/hide object histogram\n"
"to initialize tracking, select the object with mouse\n" );
cvnamedwindow( "histogram", 1 );
cvnamedwindow( "camshiftdemo", 1 );
cvsetmousecallback( "camshiftdemo", on_mouse, 0 );
cvcreatetrackbar( "vmin", "camshiftdemo", &vmin, 256, 0 );
cvcreatetrackbar( "vmax", "camshiftdemo", &vmax, 256, 0 );
cvcreatetrackbar( "smin", "camshiftdemo", &smin, 256, 0 );
for(;;)
cvcopy( frame, image, 0 );
cvcvtcolor( image, hsv, cv_bgr2hsv );
if( track_object )
}cvcalcbackproject( &hue, backproject, hist ); //計算反向投影圖backproject
cvand( backproject, mask, backproject, 0 ); //去除上下閥值外的點後的投影圖
cvcamshift( backproject, track_window, //利用camshift搜尋0-255的灰度影象
cvtermcriteria( cv_termcrit_eps | cv_termcrit_iter, 10, 1 ),
&track_comp, &track_box );
track_window = track_comp.rect; //獲得新的跟蹤視窗
if( backproject_mode )
cvcvtcolor( backproject, image, cv_gray2bgr );
if( !image->origin ) //如果為假,需要改變橢圓的角度
track_box.angle = -track_box.angle;
cvellipsebox( image, track_box, cv_rgb(255,0,0), 3, cv_aa, 0 );//畫跟蹤橢圓
}if( select_object && selection.width > 0 && selection.height > 0 )//在框住的時候反向顯示
cvshowimage( "camshiftdemo", image );
cvshowimage( "histogram", histimg );
c = cvwaitkey(10);
if( (char) c == 27 )
break;
switch( (char) c )
}cvreleasecapture( &capture );
cvdestroywindow("camshiftdemo");
return 0; }
#ifdef _eic
main(1,"camshiftdemo.c");
#endif
目標跟蹤方法 CamShift 演算法
一 概述 二 演算法流程 具體步驟如下 步驟二 根據獲得的顏色直方圖將原始輸入影象轉化成顏色概率分布影象,該過程稱為 反向投影 所謂直方圖反向投影,就是輸入影象在已知目標顏色直方圖的條件下的顏色概率密度分布圖,包含了目標在當前幀中的相干資訊。對於輸入影象中的每乙個畫素,查詢目標模型顏色直方圖,對於目...
CamShift跟蹤演算法
ifdef ch pragma package opencv endif define cv no backward compatibility ifndef eic include cv.h include highgui.h include stdio.h include ctype.h end...
目標跟蹤演算法 Camshift函式 學習筆記
在這一節中,主要講目標跟蹤的乙個重要的演算法camshift,因為它是連續自使用的meanshift,所以這2個函式opencv中都有,且都很重要。為了讓大家先達到乙個感性認識。這節主要是看懂和執行opencv中給的sample並稍加修改。camshift函式的原型為 rotatedrect cam...