视频ROI多边形区域生成

来源:互联网 发布:java敏感词过滤算法 编辑:程序博客网 时间:2024/04/29 21:42

由于视频场景检测或者跟踪,要求设置针对特定场景进行操作,博主写了一个简单的设置roi多边形区域c程序,代码仅供参考!

测试软件:vs2013,opencv249

操作说明:1、执行后待视频播放到想执行roi时按下键盘任意键即可绘制roi区域

                    2、按顺序鼠标左键点击多个点,最后点击鼠标右键,生成roi图

                    3、关闭roi图,此时需要点击图像上面的关闭按钮,不然出现不可遇见的错误


程序如下(经博主测试,代码无误!):

//鼠标事件生成roi多边形区域//作者:samylee#include <opencv/cv.h>#include <opencv/highgui.h>#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("test.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;}

测试效果如下:

    


任何问题请加唯一QQ2258205918(名称samylee)!



原创粉丝点击