在很多视频跟踪或分割中,总是需要初始化第一帧,即在第一帧上画一个框,或者标注前景与背景啊等等,今天就把初始化第一帧,在第一帧上画一个框的代码实现了一下,顺便复习一下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;
}
}
}