本文主要是介绍opencv鼠标选定感兴趣区域进行目标检测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
本文章主要对感兴趣区域ROI的操作(车辆检测)说明
在图像处理的领域,我们常常需要去设置自己感兴趣的区域(ROI,region of interest),来专注或者简化工作过程。也就是从图像中选择的一个图像区域,这个区域是图像分析所关注的重点。我们圈定这个区域,以便进行下一步的处理.而且,使用ROI指定想读入的目标,可以减少处理时间,增加精度,给图像处理带来不小的便利。
首先我们看下任意形状图形的绘制选择:
#include "cv.h" #include "highgui.h" #include <stdio.h> #include <stdlib.h> IplImage* inpaint_mask = 0; IplImage* img0 = 0, *img = 0, *inpainted = 0; CvPoint prev_pt = {-1,-1}; void on_mouse( int event, int x, int y, int flags, void* zhang) { if( !img ) return; if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) ) prev_pt = cvPoint(-1,-1);//初始化 else if( event == CV_EVENT_LBUTTONDOWN ) prev_pt = cvPoint(x,y); else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) ) {//手一直在绘画 CvPoint pt = cvPoint(x,y); if( prev_pt.x < 0 ) prev_pt = pt; cvLine( inpaint_mask, prev_pt, pt, cvScalarAll(255), 5, 8, 0 ); cvLine( img, prev_pt, pt, cvScalarAll(255), 5, 8, 0 ); prev_pt = pt; cvShowImage( "image", img ); } } int main( int argc, char** argv ) { char* filename = argc >= 2 ? argv[1] : (char*)"fruits.jpg"; if( (img0 = cvLoadImage(filename,-1)) == 0 ) return 0; printf( "Hot keys: \n" cvNamedWindow( "image", 1 ); img = cvCloneImage( img0 ); inpainted = cvCloneImage( img0 ); inpaint_mask = cvCreateImage( cvGetSize(img), 8, 1 ); cvZero( inpaint_mask ); cvZero( inpainted ); cvShowImage( "image", img ); cvShowImage( "watershed transform", inpainted ); cvSetMouseCallback( "image", on_mouse, 0 ); }
利用OpenCV库进行编程实现对感兴趣区域ROI的操作
例如:将小图标复制到大图像的指定位置中
使用到的函数:矩形的表示:Rect类—-》Rect(x,y,width,heigh)
对Rect类的解释:Rect类的成员变量有x、y、width、height,分别在左上角点的坐标和矩形的宽和高。
这篇文章讲述了鼠标选定一个感兴趣区域后,实现对目标的运动检测并计数的功能。
1.首先,暂停视频或者在视频流的第一帧中,画出感兴趣区域。
2. 然后扣出感兴趣区域
3.使用运动目标检测(在这里我以背景差分为例子)
#include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv2/imgproc/imgproc.hpp> using namespace cv; #include<iostream> #include<vector> using namespace std; /*----定义鼠标事件--画矩形区域:作用当两个车灯----*/ //第一步:全局变量 bool drawing_box = false; bool gotBox = false; Rect box; Point downPoint; /* void mouseRectHandler(int event, int x, int y, int flags, void *param) { switch (event) { case CV_EVENT_MOUSEMOVE: if (drawing_box) { box.width = x - box.x; box.height = y - box.y; } break; case CV_EVENT_LBUTTONDOWN: drawing_box = true; box = Rect(x, y, 0, 0); break; case CV_EVENT_LBUTTONUP: drawing_box = false; gotBox = true; if (box.width < 0) { box.x += box.width; box.width *= -1; } if( box.height < 0 ) { box.y += box.height; box.height *= -1; } break; default: break; } } */ void mouseRectHandler(int event, int x, int y, int flags, void *param) { switch (event) { case CV_EVENT_MOUSEMOVE: if (drawing_box) { //鼠标的移动到downPoint的右下角 if( x >=downPoint.x && y >= downPoint.y) { box.x = downPoint.x; box.y = downPoint.y; box.width = x - downPoint.x; box.height = y - downPoint.y; } //鼠标的移动到downPoint的右上角 if( x >= downPoint.x && y <= downPoint.y) { box.x = downPoint.x; box.y = y; box.width = x - downPoint.x; box.height = downPoint.y - y; } //鼠标的移动到downPoint的左上角 if( x <= downPoint.x && y <= downPoint.y) { box.x = x; box.y = y; box.width = downPoint.x - x; box.height = downPoint.y - y; } //鼠标的移动到downPoint的左下角 if( x <= downPoint.x && y >= downPoint.y) { box.x = x; box.y = downPoint.y; box.width = downPoint.x -x; box.height = y - downPoint.y; } } break; case CV_EVENT_LBUTTONDOWN: //按下鼠标,代表可以可以开始画矩形 drawing_box = true; //记录起点 downPoint = Point(x,y); break; case CV_EVENT_LBUTTONUP: //松开鼠标,代表结束画矩形 drawing_box = false; gotBox = true; break; default: break; } } // int main(int argc,char*argv[]) int main() { Mat diff_thresh;VideoCapture video("1.avi");//读取视频 // VideoCapture video(argv[1]); Mat imageROI, imageROI_BW; //判断视频是否打开 if( !video.isOpened()) return 0; bool flag;//视频中的第一帧 Mat firstFrame; flag=false; Mat frame; Mat imageROIdf,imageROIpro,imageROIdf_BW;//读取视频的第一帧 video>>frame; //复制到firstFrame中 frame.copyTo(firstFrame); //register namedWindow("video",1); setMouseCallback("video",mouseRectHandler,NULL); //画感兴趣区域 while(!gotBox) { firstFrame.copyTo(frame); rectangle(frame,box,Scalar(255,0,0),2);//画出感兴趣区域 imshow("video",frame); if(waitKey(50) == 'q')//---------很重要 break; } //remove callback setMouseCallback("video",NULL,NULL); Mat frame0,result; //视频继续 for(;;) { //读取视频 video>>frame; //判断是否有当前帧 if(!frame.data) break; //画出感兴趣区域 rectangle(frame,box,Scalar(255,255,0),2); imshow("video",frame); imageROI = frame(Rect(box.x, box.y, box.width, box.height));cvtColor(imageROI,frame0,CV_RGB2GRAY);//灰度化 medianBlur(frame0, frame0, 3);//中值滤波if (false == flag){imageROIpro = imageROI.clone();flag = true;}else{absdiff(imageROI, imageROIpro, imageROIdf);//帧间差分法imageROIpro = imageROI.clone();threshold(imageROIdf, imageROIdf_BW, 30, 255, 0);imshow("imageROIdf_BW", imageROIdf_BW);diff_thresh=imageROIdf_BW;cv::cvtColor(diff_thresh, diff_thresh, CV_RGB2GRAY);vector<vector<Point> > contours; findContours(diff_thresh, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
//CvSeq * contour = 0;
// Mat contour;
//int Num=cvFindContours( diff_thresh, storage, &contour, sizeof(CvContour), mode, CV_CHAIN_APPROX_SIMPLE); // std::cout<<"The number of Contours is:"<<Num<<std::endl; drawContours(imageROI, contours, -1, Scalar(0, 0, 255), 2);//在result上绘制轮廓 //7.查找正外接矩形 imshow("imageROI", imageROI);vector<Rect> boundRect(contours.size()); for (int i = 0; i < contours.size(); i++) { boundRect[i] = boundingRect(contours[i]); rectangle(imageROI, boundRect[i], Scalar(0, 255, 0), 2);//在result上绘制正外接矩形 } int x,y;x=contours.size();y=box.y;CvPoint point1 = cvPoint(x, y); //cout<<x;if (contours.size()>1)std::cout<<"small xuejie: "<<contours.size()<<std::endl; //std::cout << "Contours: " << coutours.size() << std::endl;
// putText(imageROI,"tracking",(100,100),FONT_HERSHEY_PLAIN,2.0,(255,255,255),2,1);//cout<<contours.size();
//4.腐蚀 /* gray=imageROIdf_BW;std::vector<std::vector<cv::Point> > contours; cv::findContours(gray, contours, // a vector of contours CV_RETR_EXTERNAL, // retrieve the external contours CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours // Print contours' length std::cout << "Contours: " << contours.size() << std::endl; std::vector<std::vector<cv::Point> >::const_iterator itContours= contours.begin(); for ( ; itContours!=contours.end(); ++itContours) { std::cout << "Size: " << itContours->size() << std::endl; } // draw black contours on white image cv::Mat result(gray.size(),CV_8U,cv::Scalar(255)); cv::drawContours(result,contours, -1, // draw all contours cv::Scalar(0), // in black 1); // with a thickness of 2 cv::namedWindow("Contours"); cv::imshow("Contours",result); //if (imageROIdf_BW.data != NULL)//{// cout << "youyidongwuti" << endl;//}*/ }imshow("imageROI", imageROI);if(waitKey(33) == 'q') break; } return 0; }
这篇关于opencv鼠标选定感兴趣区域进行目标检测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!