操作步骤:1、按下任意键盘键,视频暂停播放
2、点击鼠标左键选取感兴趣区域
3、按任意键盘键,获取roi区域
代码亲测有效
//鼠标事件生成roi多边形区域
#include
#include
#include "stdlib.h"
#include "stdio.h"
//鼠标事件入参,可用头文件包含
typedef struct {
IplImage* src1;
IplImage* dst;
int nPort;
CvPoint pre_pt;
CvPoint cur_pt;
CvPoint first_pt;
CvPoint finally_pt;
int pointnum;
CvPoint *point;
}MouseArgs;
//鼠标事件
void on_mouse(int event, int x, int y, int flags, void* ustc)
{
MouseArgs *m_arg = (MouseArgs*)ustc;
CvFont font;
cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA);
char temp[16];
if (event == CV_EVENT_LBUTTONDOWN)
{
cvCopy(m_arg->dst, m_arg->src1, NULL);
sprintf(temp, "(%d,%d)", x, y);
m_arg->pre_pt = cvPoint(x, y);
m_arg->point[m_arg->pointnum] = m_arg->pre_pt;
if (m_arg->nPort == 0)
{
m_arg->first_pt = m_arg->pre_pt;
}
//画点和直线
cvPutText(m_arg->src1, temp, m_arg->pre_pt, &font, cvScalar(0, 0, 0, 255));
cvCircle(m_arg->src1, m_arg->pre_pt, 3, cvScalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);
if (m_arg->nPort != 0)
{
cvLine(m_arg->src1, m_arg->cur_pt, m_arg->pre_pt, cvScalar(0, 255, 0, 0), 1, CV_AA, 0);
}
(m_arg->pointnum)++;
(m_arg->nPort)++;
cvShowImage("ON_MOUSE", m_arg->src1);
cvCopy(m_arg->src1, m_arg->dst, NULL);
}
else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))
{
cvCopy(m_arg->dst, m_arg->src1, NULL);
sprintf(temp, "(%d,%d)", x, y);
m_arg->cur_pt = cvPoint(x, y);
//画点和直线
cvPutText(m_arg->src1, temp, m_arg->cur_pt, &font, cvScalar(0, 0, 0, 255));
cvLine(m_arg->src1, m_arg->pre_pt, m_arg->cur_pt, cvScalar(0, 255, 0, 0), 1, CV_AA, 0);
cvShowImage("ON_MOUSE", m_arg->src1);
}
else if (event == CV_EVENT_LBUTTONUP)
{
sprintf(temp, "(%d,%d)", x, y);
m_arg->cur_pt = cvPoint(x, y);
m_arg->finally_pt = m_arg->cur_pt;
//画点和直线
cvPutText(m_arg->src1, temp, m_arg->cur_pt, &font, cvScalar(0, 0, 0, 255));
cvCircle(m_arg->src1, m_arg->cur_pt, 3, cvScalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);
cvLine(m_arg->src1, m_arg->pre_pt, m_arg->cur_pt, cvScalar(0, 255, 0, 0), 1, CV_AA, 0);
cvShowImage("ON_MOUSE", m_arg->src1);
cvCopy(m_arg->src1, m_arg->dst, NULL);
}
else if (event == CV_EVENT_RBUTTONDOWN)
{
//画直线
cvLine(m_arg->src1, m_arg->cur_pt, m_arg->first_pt, cvScalar(0, 255, 0, 0), 1, CV_AA, 0);
cvShowImage("ON_MOUSE", m_arg->src1);
cvCopy(m_arg->src1, m_arg->dst, NULL);
}
}
//做roi区域
void CreateMask(IplImage* frame, IplImage* mask)
{
uchar maskpixel;
for (int h = 0; h < mask->height; h++)
{
for (int w = 0; w < mask->width; w++)
{
maskpixel = ((uchar*)(mask->imageData + h*mask->widthStep))[w];
//屏蔽
if (maskpixel == 0)
{
((uchar*)(frame->imageData + h*frame->widthStep))[w * 3 + 0] = 0;
((uchar*)(frame->imageData + h*frame->widthStep))[w * 3 + 1] = 0;
((uchar*)(frame->imageData + h*frame->widthStep))[w * 3 + 2] = 0;
}
}
}
}
int main()
{
CvCapture *cap = cvCaptureFromAVI("H:/SourceCodeV1.1/roi/Debug/15.avi");
if (!cap) return 0;
IplImage *frame;
int pointnum = 0;
CvPoint *point = (CvPoint *)malloc(sizeof(CvPoint)* 10);;
IplImage *mask = NULL;
int flag = 0;
while (1)
{
frame = cvQueryFrame(cap);
if (!frame) break;
if (flag > 0)
{
//生成roi区域
CreateMask(frame, mask);
/* 可以去做,可以不去做
int p;
for (p = 0; p < pointnum; p++)
{
if (p != pointnum - 1)
{
cvLine(frame, point[p], point[p + 1], cvScalar(0, 255, 0, 0), 1, CV_AA, 0);
}
else
{
cvLine(frame, point[p], point[0], cvScalar(0, 255, 0, 0), 1, CV_AA, 0);
}
}
*/
}
cvShowImage("ON_MOUSE", frame);
if (cvWaitKey(1) > 0 && flag == 0)
{
//入参初始化
MouseArgs *m_arg = (MouseArgs *)malloc(sizeof(MouseArgs));
m_arg->nPort = 0;
m_arg->pre_pt.x = -1;
m_arg->pre_pt.y = -1;
m_arg->cur_pt.x = -1;
m_arg->cur_pt.y = -1;
m_arg->first_pt.x = -1;
m_arg->first_pt.y = -1;
m_arg->finally_pt.x = -1;
m_arg->finally_pt.y = -1;
m_arg->src1 = cvCloneImage(frame);
m_arg->dst = cvCloneImage(frame);
m_arg->pointnum = 0;
m_arg->point = (CvPoint *)malloc(sizeof(CvPoint)* 10);
cvSetMouseCallback("ON_MOUSE", on_mouse, (void*)m_arg);
cvShowImage("ON_MOUSE", frame);
cvWaitKey(0);
pointnum = m_arg->pointnum;
memcpy(point, m_arg->point, sizeof(CvPoint)* 10);
//生成mask图
mask = cvCreateImage(cvSize(frame->width, frame->height), 8, 1);
for (int h = 0; h < mask->height; h++)
{
for (int w = 0; w < mask->width; w++)
{
cvSet2D(mask, h, w, cvScalar(0, 0, 0, 0));
}
}
cvFillConvexPoly(mask, m_arg->point, m_arg->pointnum, CV_RGB(255, 255, 255), CV_AA, 0);
flag++;
//释放内存
cvReleaseImage(&(m_arg->src1));
cvReleaseImage(&(m_arg->dst));
free(m_arg->point);
free(m_arg);
}
else if (cvWaitKey(1) > 0 && flag > 0)
{
break;
}
}
//释放内存
free(point);
cvReleaseCapture(&cap);
cvReleaseImage(&mask);
return 0;
}
效果图