本文章主要对感兴趣区域ROI的操作(车辆检测)说明
在图像处理的领域,我们常常需要去设置自己感兴趣的区域(ROI,region of interest),来专注或者简化工作过程。也就是从图像中选择的一个图像区域,这个区域是图像分析所关注的重点。我们圈定这个区域,以便进行下一步的处理.而且,使用ROI指定想读入的目标,可以减少处理时间,增加精度,给图像处理带来不小的便利。
首先我们看下任意形状图形的绘制选择:
#include "cv.h"
#include "highgui.h"
#include
#include
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
#include
#include
using namespace cv;
#include
#include
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 > 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:"<
drawContours(imageROI, contours, -1, Scalar(0, 0, 255), 2);//在result上绘制轮廓
//7.查找正外接矩形
imshow("imageROI", imageROI);
vector 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<
if (contours.size()>1)
std::cout<<"small xuejie: "<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<
//4.腐蚀
/* gray=imageROIdf_BW;
std::vector > 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 >::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;
}