目標跟蹤之初始跟蹤區域的選定-示例

示例Demo的基本功能

首先讀取待跟蹤圖片集文件目錄中第一張(第一幀),用鼠標選定一個待跟蹤的矩形區域,然後按空格鍵繼續處理後面的圖片。

實驗環境:vs2010 + opencv2.4.2

代碼示例

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include "opencv2/video/tracking.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <string.h>

using namespace cv;
using namespace std;

void drawObjectRectangle(int event, int x, int y, int flags, void*);//鼠標處理事件,畫一個矩形作爲跟蹤區域
void readImageSequenceFiles(char* ImgFilePath,vector <string> &imgNames);
/*  Description: search the image names in the image sequences 
    Arguments:
	-ImgFilePath: path of the image sequence
	-imgNames:  vector that stores image name
*/

Mat firstFrame;
Point previousPoint, currentPoint;
Rect initObjectRect; // [x y width height] tracking position
bool lButtonDownFlag = false;

int main(int argc, char * argv[])
{
	char imgFilePath[100];
    memset(imgFilePath, 0, sizeof(imgFilePath));
	strcpy(imgFilePath,"./data");//跟蹤圖片集的路徑

	char tmpDirPath[MAX_PATH+1];

	vector <string> imgNames;
	readImageSequenceFiles(imgFilePath,imgNames);

	Mat frame;
	Mat grayImg;

	sprintf(tmpDirPath, "%s/", imgFilePath);
	imgNames[0].insert(0,tmpDirPath);
	frame = imread(imgNames[0]);
	 
	namedWindow("CT", WINDOW_AUTOSIZE);
    imshow("CT", frame);
	firstFrame = frame;
    setMouseCallback("CT", drawObjectRectangle, 0);
    waitKey(0);
	cout << initObjectRect.x << "  " << initObjectRect.y << "  " << initObjectRect.width << "  " << initObjectRect.height << endl; 

	for(int i = 1; i < imgNames.size()-1; i ++)
	{
		sprintf(tmpDirPath, "%s/", imgFilePath);
        imgNames[i].insert(0,tmpDirPath);
        		
		frame = imread(imgNames[i]);// get frame
		
		//.........可插入跟蹤處理函數

		rectangle(frame, initObjectRect, Scalar(200,0,0),2);// Draw rectangle

		imshow("CT", frame);// Display
		waitKey(1);		
	}
	return 0;
}

void drawObjectRectangle(int event, int x, int y, int flags, void*)
{
	if(event == EVENT_LBUTTONDOWN)
	{
		previousPoint = Point(x, y);
		lButtonDownFlag = true;
	}else if(event == EVENT_MOUSEMOVE && lButtonDownFlag == true){
		Mat tmp;
        firstFrame.copyTo(tmp);
        currentPoint = Point(x, y);
        rectangle(tmp, previousPoint, currentPoint, Scalar(200, 0, 0), 2);
        imshow("CT", tmp);
	}else if(event == EVENT_LBUTTONUP){
		initObjectRect.x = previousPoint.x;
		initObjectRect.y = previousPoint.y;
		initObjectRect.width = abs(currentPoint.x - previousPoint.x);
		initObjectRect.height = abs(currentPoint.y - previousPoint.y);
		lButtonDownFlag = false;
	}
}

//將./data目錄下的圖片名字全部存入imageNames
void readImageSequenceFiles(char* imgFilePath,vector <string> &imgNames)
{	
	imgNames.clear();

	char tmpDirSpec[MAX_PATH+1];
	sprintf (tmpDirSpec, "%s/*", imgFilePath);
	 
	WIN32_FIND_DATA f;
	HANDLE h = FindFirstFile(tmpDirSpec , &f); //read . --modified by Lumengru
	if(h != INVALID_HANDLE_VALUE)
	{
		FindNextFile(h, &f);	//read ..  --modified by Lumengru
		FindNextFile(h, &f);	//read the first picture  --modified by Lumengru
		do
		{
			imgNames.push_back(f.cFileName);
		} while(FindNextFile(h, &f)); 
	}
	FindClose(h);	
}

用鼠標左鍵點擊拖拽畫一個矩形,之後按空格鍵可以處理剩下的圖片。