之前一直在做车道线检测的论文以及实验,本人也是目前在学c++编程中的新手小白一个,所以也想写这篇文章,记录下自己怎么在霍夫检测车道线中,通过鼠标事件随机设定roi区域,检测所感兴趣区域的车道线;当然这代码最初也只是为了发表论文实验所写的,对于实际应用还有许多的不成熟性。
众所周知,通过边缘检测得到的图片包含了很多环境信息,这些是我们不感兴趣的,需要提取我们需要都得信息。对于普通的直线形车道,观察图片可知,车道先一般位于图片下方的一个梯形区域,手动设定4个点,组成梯形区域的四个顶点。利用fillConvexPoly函数如下可以画出多边形,这个函数共有4个参数:空图(大小与原图一致),顶点信息,多边形的边数,线条颜色。
函数示例:fillConvexPoly(mask,PointArray,4,Scalar(255));
将梯形掩模区域与原图进行bitwise_and 操作,可以只得到感兴趣区域内的边缘检测图,从途中可以看出只有车道线信息。bitwise_and 函数是将两张图片做“与”操作,共有3个输入参数,分别是:掩模图, 原图,输出图。需要注意的是,三张图的大小和颜色通道数量。
函数示例:bitwise_and(mask,image_canny,dstImg);
但是以上roi的区域的选取方式不适用目前在做的论文,该论文中的主要实验是针对弯道进行车道线检测,因此就准备主要利用setMouseCallback()和onMouse()两个函数来编写可以鼠标交互选取霍夫检测roi区域的代码
代码如下(示例):
#include
#include
#include
using namespace std;
using namespace cv;
Point PointArray[20];
int clickTimes = 0;
void onMouse(int event, int x, int y, int flags, void *utsc)
{
if (event == EVENT_LBUTTONUP)
{
PointArray[clickTimes].x = x;
PointArray[clickTimes].y = y;
cout << "第" << clickTimes << "个点 " << " ";
cout << "PointArray[clickTimes].x:" << " " << PointArray[clickTimes].x
<< ' ' << "PointArray[clickTimes].y" << PointArray[clickTimes].y << endl;
clickTimes++;
}
if (event == EVENT_RBUTTONUP)
{
Mat src = imread("veh2.jpg");
Mat mat_gray, mat_guass, mat_canny, mat_hough;
cvtColor(src, mat_gray, CV_RGB2GRAY);
//高斯降噪
GaussianBlur(mat_gray, mat_guass, Size(9, 9), 0, 0);
//binary
//threshold(dst, dst, 125, 255, THRESH_BINARY);
//canny边缘检测
Canny(mat_guass, mat_canny, 50, 100, 3);
//ROI感兴趣区域的选定
Mat dstimg;
Mat mask = Mat::zeros(mat_canny.size(), CV_8UC1);
fillConvexPoly(mask, PointArray, clickTimes, Scalar(255));
bitwise_and(mask, mat_canny, dstimg);
imshow("ROIresult", dstimg);
//HoughLine Detect
vector<Vec4i> lines;
HoughLinesP(dstimg, lines, 1, CV_PI / 180, 50, 5, 50);
for (size_t i = 0; i < lines.size(); i++)
{
Vec4i& linex = lines[i];
int dx = linex[2] - linex[0];
int dy = linex[3] - linex[1];
double angle = atan2(double(dy), dx) * 180 / CV_PI;
line(src, cv::Point(linex[0], linex[1]), cv::Point(linex[2], linex[3]), cv::Scalar(255, 0, 0), 2);
}
imshow("Houghresult", src);
imwrite("E:/霍夫智能变换小论文/霍夫智能变换实验照片/veh2Houghres.jpg", src);
}
}
int main()
{
Mat img = imread("veh2.jpg");
if (img.empty())
{
cout << "Please input the right image" << endl;
return -1;
}
imshow("Source image", img);
setMouseCallback("Source image", onMouse);
waitKey(0);
return 0;
}
首先实验图片如下:
经过鼠标选取自定义的roi区域,通过mask处理,图片如下:
最后本文只是作为学习过程中的一个分享,作用更多只是为了做实验选取检测弯道的自定义区域所编写,对于做车道线检测与项目应用来说,一次次的鼠标交互选取roi区域显得会很繁琐,更不实际。本文也只是作为记录自己学习过程中的感悟之用。