本文转自http://blog.csdn.net/sangni007/article/details/8112486
在很多视频跟踪或分割中,总是需要初始化第一帧,即在第一帧上画一个框,或者标注前景与背景啊等等,今天就把初始化第一帧,在第一帧上画一个框的代码实现了一下,顺便复习一下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;
- }
- }
- }
#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; } } }