在很多视频跟踪或分割中,总是需要初始化第一帧,即在第一帧上画一个框,或者标注前景与背景啊等等,今天就把初始化第一帧,在第一帧上画一个框的代码实现了一下,顺便复习一下OpenCV里面的鼠标召回事件,在此贴上代码,与大家分享,也方便以后查找。
#include "opencv2/opencv.hpp" #include "opencv2/highgui/highgui.hpp" #include <string> #include <iostream> #include <stdio.h> using namespace cv; using namespace std; //最多对一个对象进行跟踪; #define MAX_OBJECTS 1 //传递参数的class class params { public: Point loc1,loc2; string win_name; Mat src; Mat cur; int n; //记录对象个数 params() : n(0) {} // ~params(); }; //鼠标事件 void mouseEvent(int event, int x, int y, int flags, void* param) { static bool check_line_state = FALSE; Mat tmp; params* p = (params*)param; //按下鼠标左键,存储初始位置; if( event == CV_EVENT_LBUTTONDOWN ) { if (p->n == MAX_OBJECTS)//判断是否已经有了跟踪对象; { cout<<"Fail! \n Only Can Tracking One Object!"<<endl; return ; } p->loc1.x = x; p->loc1.y = y; check_line_state = TRUE; } //按下鼠标左键且鼠标移动,画矩形框; else if (check_line_state && event == CV_EVENT_MOUSEMOVE) { if (p->n == MAX_OBJECTS)//判断是否已经有了跟踪对象; { cout<<"Fail! \n Only Can Tracking One Object!"<<endl; return ; } p->src.copyTo(tmp); rectangle(tmp, p->loc1, Point(x,y), CV_RGB(255,0,0), 2, 8 ); imshow(p->win_name,tmp); } //左键弹起,画框结束; else if(event == CV_EVENT_LBUTTONUP) { if (p->n == MAX_OBJECTS)//判断是否已经有了跟踪对象; { cout<<"Fail! \n Only Can Tracking One Object!"<<endl; return ; } p->loc2.x = x; p->loc2.y = y; rectangle(p->src, p->loc1, Point(x,y), CV_RGB(255,0,0), 2, 8 ); imshow(p->win_name,p->src); p->n++; check_line_state = FALSE; } } //初始化第一帧,画出要跟踪的对象 void InitialVideo(Mat& src, Rect& rect) { params p; src.copyTo(p.src); p.win_name = "Initial Window"; imshow(p.win_name, src); //鼠标召回事件 setMouseCallback(p.win_name, &mouseEvent, &p); cout<<"draw rect & press any key to end"<<endl; waitKey(); //把得到的位置赋给rect rect.x = min(p.loc1.x, p.loc2.x); rect.y = min(p.loc1.y, p.loc2.y); rect.width = abs(p.loc1.x - p.loc2.x); rect.height = abs(p.loc1.y - p.loc2.y); destroyWindow("Initial Window"); } int main() { //从默认摄像头输入 VideoCapture cap(0); //从视频输入 //string filename = "D:/soccer.avi"; //VideoCapture cap(filename); if(!cap.isOpened()) // check if we succeeded { cout<<"couldn't open video file"<<endl; return -1; } Mat frame; bool isFirstFrame = TRUE; Rect rect; cap>>frame;//可能是因为电脑问题,导致第一帧显示不出来,所以就把第一帧先读一次 for (;;) { cap>>frame; //初始化第一帧 if ( isFirstFrame) { InitialVideo(frame,rect); isFirstFrame = FALSE; } //其他操作 rectangle(frame, rect, CV_RGB(255,0,0), 2, 8 ); imshow("showSrc",frame); char key = (char)waitKey(5); switch (key) { case 27: return 0; case ' ' : cout<<"save process"<<endl; break; default: break; } } }