這是基於顏色識別的物體追蹤
不廢話
直接看代碼
這是Opencv3的代碼
//---------------------------------【頭文件、命名空間包含部分】---------------------------- // 描述:包含程序所使用的頭文件和命名空間 //------------------------------------------------------------------------------------------------- #include "opencv2/video/tracking.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream> #include <ctype.h> using namespace cv; using namespace std; //-----------------------------------【全局變量聲明】----------------------------------------- // 描述:聲明全局變量 //------------------------------------------------------------------------------------------------- Mat image; bool backprojMode = false; bool selectObject = false; int trackObject = 0; bool showHist = true; Point origin; Rect selection; int vmin = 10, vmax = 256, smin = 30; //--------------------------------【onMouse( )回調函數】------------------------------------ // 描述:鼠標操作回調 //------------------------------------------------------------------------------------------------- static void onMouse( int event, int x, int y, int, void* ) { if( selectObject ) { selection.x = MIN(x, origin.x); selection.y = MIN(y, origin.y); selection.width = std::abs(x - origin.x); selection.height = std::abs(y - origin.y); selection &= Rect(0, 0, image.cols, image.rows); } switch( event ) { //此句代碼的OpenCV2版為: //case CV_EVENT_LBUTTONDOWN: //此句代碼的OpenCV3版為: case EVENT_LBUTTONDOWN: origin = Point(x,y); selection = Rect(x,y,0,0); selectObject = true; break; //此句代碼的OpenCV2版為: //case CV_EVENT_LBUTTONUP: //此句代碼的OpenCV3版為: case EVENT_LBUTTONUP: selectObject = false; if( selection.width > 0 && selection.height > 0 ) trackObject = -1; break; } } //--------------------------------【help( )函數】---------------------------------------------- // 描述:輸出幫助信息 //------------------------------------------------------------------------------------------------- static void ShowHelpText() { cout << "\n\n\t此Demo顯示了基於均值漂移的追蹤(tracking)技術\n" "\t請用鼠標框選一個有顏色的物體,對它進行追蹤操作\n"; cout << "\n\n\t操作說明: \n" "\t\t用鼠標框選對象來初始化跟蹤\n" "\t\tESC - 退出程序\n" "\t\tc - 停止追蹤\n" "\t\tb - 開/關-投影視圖\n" "\t\th - 顯示/隱藏-對象直方圖\n" "\t\tp - 暫停視頻\n"; } const char* keys = { "{1| | 0 | camera number}" }; //-----------------------------------【main( )函數】-------------------------------------------- // 描述:控制台應用程序的入口函數,我們的程序從這里開始 //------------------------------------------------------------------------------------------------- int main( int argc, const char** argv ) { ShowHelpText(); VideoCapture cap; Rect trackWindow; int hsize = 16; float hranges[] = {0,180}; const float* phranges = hranges; cap.open(0); if( !cap.isOpened() ) { cout << "不能初始化攝像頭\n"; } namedWindow( "Histogram", 0 ); namedWindow( "CamShift Demo", 0 ); setMouseCallback( "CamShift Demo", onMouse, 0 ); createTrackbar( "Vmin", "CamShift Demo", &vmin, 256, 0 ); createTrackbar( "Vmax", "CamShift Demo", &vmax, 256, 0 ); createTrackbar( "Smin", "CamShift Demo", &smin, 256, 0 ); Mat frame, hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj; bool paused = false; for(;;) { if( !paused ) { cap >> frame; if( frame.empty() ) break; } frame.copyTo(image); if( !paused ) { cvtColor(image, hsv, COLOR_BGR2HSV); if( trackObject ) { int _vmin = vmin, _vmax = vmax; inRange(hsv, Scalar(0, smin, MIN(_vmin,_vmax)), Scalar(180, 256, MAX(_vmin, _vmax)), mask); int ch[] = {0, 0}; hue.create(hsv.size(), hsv.depth()); mixChannels(&hsv, 1, &hue, 1, ch, 1); if( trackObject < 0 ) { Mat roi(hue, selection), maskroi(mask, selection); calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges); //此句代碼的OpenCV3版為: normalize(hist, hist, 0, 255, NORM_MINMAX); //此句代碼的OpenCV2版為: //normalize(hist, hist, 0, 255, CV_MINMAX); trackWindow = selection; trackObject = 1; histimg = Scalar::all(0); int binW = histimg.cols / hsize; Mat buf(1, hsize, CV_8UC3); for( int i = 0; i < hsize; i++ ) buf.at<Vec3b>(i) = Vec3b(saturate_cast<uchar>(i*180./hsize), 255, 255); //此句代碼的OpenCV3版為: cvtColor(buf, buf, COLOR_HSV2BGR); //此句代碼的OpenCV2版為: //cvtColor(buf, buf, CV_HSV2BGR); for( int i = 0; i < hsize; i++ ) { int val = saturate_cast<int>(hist.at<float>(i)*histimg.rows/255); rectangle( histimg, Point(i*binW,histimg.rows), Point((i+1)*binW,histimg.rows - val), Scalar(buf.at<Vec3b>(i)), -1, 8 ); } } calcBackProject(&hue, 1, 0, hist, backproj, &phranges); backproj &= mask; RotatedRect trackBox = CamShift(backproj, trackWindow, //此句代碼的OpenCV3版為: TermCriteria( TermCriteria::EPS | TermCriteria::COUNT, 10, 1 )); //此句代碼的OpenCV2版為: //TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 )); if( trackWindow.area() <= 1 ) { int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5)/6; trackWindow = Rect(trackWindow.x - r, trackWindow.y - r, trackWindow.x + r, trackWindow.y + r) & Rect(0, 0, cols, rows); } if( backprojMode ) cvtColor( backproj, image, COLOR_GRAY2BGR ); //此句代碼的OpenCV3版為: ellipse( image, trackBox, Scalar(0,0,255), 3, LINE_AA ); //此句代碼的OpenCV2版為: //ellipse( image, trackBox, Scalar(0,0,255), 3, CV_AA ); } } else if( trackObject < 0 ) paused = false; if( selectObject && selection.width > 0 && selection.height > 0 ) { Mat roi(image, selection); bitwise_not(roi, roi); } imshow( "CamShift Demo", image ); imshow( "Histogram", histimg ); char c = (char)waitKey(10); if( c == 27 ) break; switch(c) { case 'b': backprojMode = !backprojMode; break; case 'c': trackObject = 0; histimg = Scalar::all(0); break; case 'h': showHist = !showHist; if( !showHist ) destroyWindow( "Histogram" ); else namedWindow( "Histogram", 1 ); break; case 'p': paused = !paused; break; default: ; } } return 0; }
拜拜啦 兄弟們