github的代码,添加了一点自己的改动和注释
大概思想 滤波 增强 roi区域划分 canny边缘提取 hough直线检测
主要的超参在cannny检测阈值以及hough直线检测阈值上
roadDetection.h
#pragma once
#include
#include
#include
#include
#include
#include
#include "opencv2/imgproc/imgproc_c.h"
//B样条曲线拟合
//双曲线拟合
using namespace std;
using namespace cv;
#define INPUT "road\\001.png"
#define OUTPUT "result\\001.png"
class RoadDetection
{
public:
RoadDetection(const Mat& image=Mat ())
:readImage(image)
{
left_flag = false;
right_flag = false;
writeImage = readImage;
}
Mat result()
{
return writeImage;
}
//去噪
void deNoise(Mat inputImage, Mat& outputImage);
//设置ROI
void mask(Mat inputImage, Mat& outputImage);
//形态学闭运算
void CloseOperation(Mat inputImage, Mat& outputImage);
//亮度特征
void Brightness(Mat inputImage, Mat& outputImage);
//颜色阈值
void colorThreshold(Mat inputImage, Mat& outputImage);
void HistEqualize(Mat inputImage, Mat& outputImage);
//边缘检测
void edgeDetector(Mat inputImage, Mat& outputImage);
//霍夫线概率变换
vector<Vec4i> houghLines(Mat inputImage);
//筛选线段
void lineSeparation(const vector<Vec4i>& lines, vector<std::vector<cv::Vec4i> >& output);
void select_lines(const vector<std::vector<cv::Vec4i> >& output, vector<std::vector<cv::Vec4i> >& selectLines);
vector<Point> regression(vector<vector<Vec4i> > left_right_lines, Mat inputImage);
// void findSide(const Mat& inputImage);
void findTop(vector<vector<Vec4i> > output);
bool predictTurn(int right_x, int left_x);
bool polynomial_curve_fit(vector<Vec4i> lines, int n);
//检测车道线主流程
void detection();
private:
Mat readImage;
Mat writeImage;
bool left_flag;
bool right_flag;
Point right_b; //右直线点
double right_m; //右直线斜率
Point left_b; //左直线点
double left_m; //左直线斜率
int top_y;
int canTh = 150;
};
roadDetection.cpp
#include
#include
#include
#include"roadDetection.h"
#include
//#define __TEST__
#define __DEBUG__
using namespace std;
using namespace cv;
//调试时显示处理后的图片
void myShow(std::string str, Mat inputImage)
{
#ifdef __DEBUG__
imshow(str, inputImage);
#endif
}
void testShow(std::string str, Mat inputImage)
{
#ifdef __TEST__
imshow(str, inputImage);
#endif
}
//高斯去噪
void RoadDetection::deNoise(Mat inputImage, Mat& outputImage)
{
GaussianBlur(inputImage, outputImage, Size(3, 3), 0, 0);
//blur(inputImage, outputImage, Size(7, 7)); //均值
//medianBlur(inputImage, outputImage, 7); //中值
//bilateralFilter(inputImage, outputImage, 25, 25 * 2, 25 / 2); //双边
}
//闭运算
void RoadDetection::CloseOperation(Mat inputImage, Mat& outputImage)
{
Mat element = getStructuringElement(MORPH_RECT, Size(7, 7));
//进行形态学操作
//morphologyEx(inputImage, outputImage, MORPH_GRADIENT, element);
//闭运算
morphologyEx(inputImage, outputImage, MORPH_CLOSE, element);
//morphologyEx(inputImage, outputImage, MORPH_OPEN, element);
//morphologyEx(inputImage, outputImage, MORPH_DILATE, element);
//膨胀
//dilate(inputImage, outputImage, element);
//腐蚀
//erode(inputImage, outputImage, element);
}
//设置ROI
void RoadDetection::mask(Mat inputImage, Mat& outputImage) {
Mat mask = Mat::zeros(inputImage.size(), inputImage.type());
Point pts[4] = {
//Point(inputImage.cols / 4, inputImage.rows / 4),
Point(0, inputImage.rows>>1),
//Point(inputImage.cols /4, inputImage.rows >> 1),
Point(0, inputImage.rows),
Point(inputImage.cols, inputImage.rows),
Point(inputImage.cols, inputImage.rows >>1)
//Point(inputImage.cols/4*3, inputImage.rows >> 1)
};
// Create a binary polygon mask
fillConvexPoly(mask, pts, 4, Scalar(255, 255, 255));
// Multiply the edges image and the mask to get the output
bitwise_and(inputImage, mask, outputImage);
定义一个Mat类型并给其设定ROI区域
//Mat imageROI;
方法一
//imageROI = inputImage(Rect(0, inputImage.rows >> 1, inputImage.cols, inputImage.rows>>1));
}
Mat Histogram(Mat inputImage)
{
/// 分割成3个单通道图像 ( R, G 和 B )
vector<Mat> rgb_planes;
split(inputImage, rgb_planes);
/// 设定bin数目
int histSize = 255;
/// 设定取值范围 ( R,G,B) )
float range[] = { 0, 255 };
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
Mat r_hist, g_hist, b_hist;
/// 计算直方图:
calcHist(&rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate);
//calcHist(&rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate);
//calcHist(&rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate);
// 创建直方图画布
int hist_w = 400; int hist_h = 400;
int bin_w = cvRound((double)hist_w / histSize);
Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
/// 将直方图归一化到范围 [ 0, histImage.rows ]
normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
//normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
//normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
/// 在直方图画布上画出直方图
for (int i = 1; i < histSize; i++)
{
line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
Point(bin_w*(i), hist_h - cvRound(r_hist.at<float>(i))),
Scalar(255, 255, 255), 2, 8, 0);
//line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at(i - 1))),
// Point(bin_w*(i), hist_h - cvRound(g_hist.at(i))),
// Scalar(0, 255, 0), 2, 8, 0);
//line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at(i - 1))),
// Point(bin_w*(i), hist_h - cvRound(b_hist.at(i))),
// Scalar(255, 0, 0), 2, 8, 0);
}
return histImage;
}
//直方图均衡化
void RoadDetection::HistEqualize(Mat inputImage, Mat& outputImage)
{
cvtColor(inputImage, inputImage, CV_RGB2GRAY);
testShow("cvtColor", inputImage);
testShow("均衡化前直方图", Histogram(inputImage));
vector<Mat> splitBGR(inputImage.channels());
split(inputImage, splitBGR);
for (int i = 0; i < inputImage.channels(); ++i)
{
equalizeHist(splitBGR[i], splitBGR[i]);
}
Mat mergeImg;
merge(splitBGR, mergeImg);
mergeImg.copyTo(outputImage);
testShow("均衡化后直方图", Histogram(outputImage));
//outputImage.convertTo(outputImage, -1, 1, 20);
//testShow("convertTo", outputImage);
}
//亮度特征
void RoadDetection::Brightness(Mat inputImage, Mat& outputImage)
{
//cvtColor(inputImage, inputImage, CV_RGB2GRAY);
//testShow("cvtColor", inputImage);
//Mat tmp1,tmp2;
//threshold(inputImage, tmp1, 140, 255, THRESH_TOZERO);
//threshold(inputImage, tmp1, 245, 255, THRESH_BINARY);
//testShow("250", tmp1);
//threshold(inputImage, tmp2, 200, 255, THRESH_BINARY);
//testShow("200", tmp2);
//bitwise_and(tmp1, tmp2, outputImage);
//addWeighted(tmp1, 1, tmp2, 1, 0.0, outputImage);
threshold(inputImage, outputImage, 100, 255, THRESH_BINARY);
}
//颜色阈值
void RoadDetection::colorThreshold(Mat inputImage, Mat& outputImage)
{
//cvtColor(inputImage, outputImage, CV_RGB2GRAY);
//threshold(inputImage, outputImage, 140, 255, THRESH_BINARY);
Mat bgr,hsv, mask,result;
testShow("input", inputImage);
inputImage.convertTo(bgr, CV_32FC3, 1.0 / 255, 0);
testShow("bgr", bgr);
cvtColor(bgr, hsv, COLOR_BGR2HSV);
testShow("COLOR_BGR2HSV", hsv);
inRange(hsv, Scalar(0, 0, (float)(230)/255), Scalar(90, (float)255/255, (float)(255)/255), mask);
//inRange(hsv, Scalar(0, 0, (float)(150) / 255), Scalar(90, (float)255 / 255, (float)(255) / 255), mask);
testShow("inRange", mask);
//只保留
//result = Mat::zeros(bgr.size(), CV_32FC3);
//for (int r = 0; r < bgr.rows; r++)
//{
// for (int c = 0; c < bgr.cols; c++)
// {
// if (mask.at(r, c) == 255)
// {
// result.at(r, c) = bgr.at(r, c);
// }
// }
//}
result = mask;
result.convertTo(result, CV_8UC3, 255.0, 0);
outputImage = result.clone();
}
//边缘检测
void RoadDetection::edgeDetector(Mat inputImage, Mat& outputImage)
{
//testShow("threshold", outputImage);
cout << canTh << endl;
Canny(inputImage, outputImage, canTh, 10, 3); //Canny边缘检测算子
//imshow("111111", outputImage);
//waitKey(0);
//Laplacian(inputImage, outputImage, CV_16S, 3, 1, 0, BORDER_DEFAULT); //拉普拉斯算子
//convertScaleAbs(outputImage, outputImage);
//Soble边缘检测算子
//Mat grad_x, grad_y;
//Mat abs_grad_x, abs_grad_y;
【3】求 X方向梯度
//Sobel(inputImage, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
//convertScaleAbs(grad_x, abs_grad_x);
//imshow("【效果图】 X方向Sobel", abs_grad_x);
【4】求Y方向梯度
//Sobel(inputImage, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);
//convertScaleAbs(grad_y, abs_grad_y);
//imshow("【效果图】Y方向Sobel", abs_grad_y);
【5】合并梯度(近似)
//addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, outputImage);
//imshow("【效果图】整体方向Sobel", outputImage);
}
//霍夫线概率变换
vector<Vec4i> RoadDetection::houghLines(Mat inputImage)
{
vector<Vec4i> line;
HoughLinesP(inputImage, line, 1, CV_PI / 180, 40, 20, 10);
return line;
}
//画线
void drawDetectedLines(Mat &image, vector<Vec4i> lines, Scalar color = Scalar(255, 255, 255))
{
vector<Vec4i>::const_iterator it2 = lines.begin();
while (it2 != lines.end()) {
Point pt1((*it2)[0], (*it2)[1]);
Point pt2((*it2)[2], (*it2)[3]);
line(image, pt1, pt2, color);
++it2;
}
}
//selected_lines
void RoadDetection::lineSeparation(const vector<Vec4i>& lines, vector<std::vector<cv::Vec4i> >& output)
{
size_t j = 0;
Point ini;
Point fini;
double slope_thresh = 0.3;
vector<double> slopes;
vector<Vec4i> selected_lines;
vector<Vec4i> right_lines, left_lines;
// 根据斜率筛选
for (auto i : lines)
{
ini = cv::Point(i[0], i[1]);
fini = cv::Point(i[2], i[3]);
// Basic algebra: slope = (y1 - y0)/(x1 - x0)
//计算斜率
double slope = (static_cast<double>(fini.y) - static_cast<double>(ini.y)) / (static_cast<double>(fini.x) - static_cast<double>(ini.x) + 0.00001);
// If the slope is too horizontal, discard the line
// If not, save them and their respective slope
//如果这条线的斜率太过于水平(斜率大于0.3),忽略这条直线
//否则保存同时保存斜率
if (std::abs(slope) > slope_thresh)
{
slopes.push_back(slope);
selected_lines.push_back(i);
}
}
// selected_lines存储了所有斜率满足要求的直线的两个点Vec4i,slopes存储了他们对应的斜率
// Split the lines into right and left lines
//依据图像的中心点来区分左右 列数/2
double img_center = static_cast<double>((readImage.cols / 2));
while (j < selected_lines.size()) {
//循环遍历所有筛选的直线 ini为起始点 fini为结束点
ini = Point(selected_lines[j][0], selected_lines[j][1]);
fini = Point(selected_lines[j][2], selected_lines[j][3]);
// Condition to classify line as left side or right side
//将筛选的直线依据刚才求得中心分为左边、右边
//并且在右边的线(起点、终点的x值大于中心点)的斜率应该大于0且小于0.5
//并且在左边的线(起点、终点的x值小于中心点)的斜率应该小于0
if ((slopes[j] > 0.3 && slopes[j] < 0.5) && fini.x > img_center && ini.x > img_center) {
right_lines.push_back(selected_lines[j]);
right_flag = true;
}
else if ((slopes[j] < -0.3 && slopes[j] > -0.40 )&& fini.x < img_center && ini.x < img_center) {
left_lines.push_back(selected_lines[j]);
left_flag = true;
}
j++;
}
output[0] = right_lines;
output[1] = left_lines;
}
void RoadDetection::select_lines(const vector<std::vector<cv::Vec4i> >& output, vector<std::vector<cv::Vec4i> >& selectLines)
{
for (auto i : output[1])
{
cout << i << endl;
}
}
vector<Point> RoadDetection::regression(vector<vector<Vec4i> > left_right_lines, Mat inputImage)
{
vector<Point> output(4);
Point ini;
Point fini;
Point ini2;
Point fini2;
Vec4d right_line;
Vec4d left_line;
vector<Point> right_pts;
vector<Point> left_pts;
// If right lines are being detected, fit a line using all the init and final points of the lines
//如果检测到存在右边的线,就获取一条直线来替代所有的直线
if (right_flag == true) {
//将右边区域所有线段的端点(起点和终点)加入到right_pts中,利用fitLine来求解一条直线
// 所求直线思想:求取一条到right_pts中所有点距离最近的直线,可采用L2距离及欧氏距离
//line[0]、line[1] 存放的是直线的方向向量,
//double cos_theta = line[0]; double sin_theta = line[1];
//line[2]、line[3] 存放的是直线上一个点的坐标。
for (auto i : left_right_lines[0]) {
ini = Point(i[0], i[1]);
fini = Point(i[2], i[3]);
right_pts.push_back(ini);
right_pts.push_back(fini);
}
if (right_pts.size() > 0) {
// The right line is formed here
fitLine(right_pts, right_line, DIST_L2, 0, 0.01, 0.01);
right_m = right_line[1] / right_line[0];
right_b = Point(right_line[2], right_line[3]);
}
}
//同右边的处理
// If left lines are being detected, fit a line using all the init and final points of the lines
if (left_flag == true) {
for (auto j : left_right_lines[1]) {
ini2 = cv::Point(j[0], j[1]);
fini2 = cv::Point(j[2], j[3]);
left_pts.push_back(ini2);
left_pts.push_back(fini2);
}
if (left_pts.size() > 0) {
// The left line is formed here
fitLine(left_pts, left_line, DIST_L2, 0, 0.01, 0.01);
left_m = left_line[1] / left_line[0];
left_b = Point(left_line[2], left_line[3]);
}
}
// One the slope and offset points have been obtained, apply the line equation to obtain the line points
//依据上文求的斜率left_m和直线上的一个点的left_b求解出直线
//求当y为 ini_y fin_y时的x,求得左右两条车道线的起点和终点
cout << "右边斜率:" << right_m << endl;
cout << "左边斜率:" << left_m << endl;
int ini_y = inputImage.rows;
int fin_y = inputImage.rows/3*2;
double right_ini_x = ((ini_y - right_b.y) / right_m) + right_b.x;
double right_fin_x = ((fin_y - right_b.y) / right_m) + right_b.x;
double left_ini_x = ((ini_y - left_b.y) / left_m) + left_b.x;
double left_fin_x = ((fin_y - left_b.y) / left_m) + left_b.x;
output[0] = Point(right_ini_x, ini_y);
output[1] = Point(right_fin_x, fin_y);
output[2] = Point(left_ini_x, ini_y);
output[3] = Point(left_fin_x, fin_y);
return output;
}
bool RoadDetection::predictTurn(int right_x, int left_x) {
std::string output;
double vanish_x;
double thr_vp = 32;
double img_center = (right_x + left_x)>>1; //车道中心点
// The vanishing point is the point where both lane boundary lines intersect
vanish_x = static_cast<double>(((right_m*right_b.x) - (left_m*left_b.x) - right_b.y + left_b.y) / (right_m - left_m));
// The vanishing points location determines where is the road turning
//if (vanish_x >= (img_center - thr_vp) && vanish_x <= (img_center + thr_vp))
// output = "Straight";
//else if (vanish_x < (img_center - thr_vp))
// output = "Left Turn";
//else if (vanish_x > (img_center + thr_vp))
// output = "Right Turn";
if (vanish_x >= (img_center - thr_vp) && vanish_x <= (img_center + thr_vp))
return true;
else
return false;
/*circle(writeImage, Point(img_center, writeImage.rows / 3 * 2), 5, Scalar(0, 0, 0), 2, 8, 0);
circle(writeImage, Point(vanish_x, writeImage.rows>>1), 5, Scalar(0, 0, 0), 2, 8, 0);*/
//cout << "right_b " << right_b << " right_m " << right_m <<" left_b "<< left_b <<" left_m " << left_m << endl;
//cout << vanish_x - img_center << endl;
//return output;
}
//bool RoadDetection::polynomial_curve_fit(vector lines, int n, bool left_flge)
//{
// vector key_point;
// vector poly_point;
// Mat A;
// int min_x=10000, max_x=0;
// for (auto i : lines)
// {
// key_point.push_back(Point2f(i[0], i[1]));
// key_point.push_back(Point2f(i[2], i[3]));
// if (max_x < (i[0]>i[2]?i[0]:i[2]))
// max_x = (i[0] > i[2] ? i[0] : i[2]);
// if (min_x > (i[0] < i[2] ? i[0] : i[2]))
// min_x = (i[0] < i[2] ? i[0] : i[2]);
// }
//
// if (left_flge)
// {
// min_x = left_x;
// }
// else
// {
// max_x = right_x;
// }
// //Number of key points
// int N = key_point.size();
// //构造X
// Mat X = Mat::zeros(n + 1, n + 1, CV_64FC1);
// for (int i = 0; i < n + 1; i++)
// {
// for (int j = 0; j < n + 1; j++)
// {
// for (int k = 0; k < N; k++)
// {
// X.at(i, j) = X.at(i, j) + pow(key_point[k].x, i + j);
// }
// }
// }
// //构造Y
// Mat Y = Mat::zeros(n + 1, 1, CV_64FC1);
// for (int i = 0; i < n + 1; i++)
// {
// for (int k = 0; k < N; k++)
// {
// Y.at(i, 0) = Y.at(i, 0) + pow(key_point[k].x, i) * key_point[k].y;
// }
// }
//
// A = Mat::zeros(n + 1, 1, CV_64FC1);
// //求解A
// solve(X, Y, A, DECOMP_LU);
// for (float x = min_x; x < max_x; x++)
// {
// double y = A.at(0, 0) + A.at(1, 0) * x +
// A.at(2, 0)*pow(x, 2) + A.at(3, 0)*pow(x, 3);
//
// poly_point.push_back(Point2f(x, y));
// }
//
// Point2f now, next;
// vector::iterator it = poly_point.begin();
// next = *it++;
// while (it != poly_point.end())
// {
// now = next;
// next = *it++;
// line(writeImage, now, next, Scalar(255, 255, 0), 5, 16);
// }
//
// cout << A << endl;
// cout << poly_point << endl;
// return true;
//}
bool RoadDetection::polynomial_curve_fit(vector<Vec4i> lines, int n)
{
vector<Point2f> key_point;
vector<Point2f> poly_point;
Mat A;
for (auto i : lines)
{
key_point.push_back(Point2f(i[1], i[0]));
key_point.push_back(Point2f(i[3], i[2]));
}
//Number of key points
int N = key_point.size();
//构造X
Mat X = Mat::zeros(n + 1, n + 1, CV_64FC1);
for (int i = 0; i < n + 1; i++)
{
for (int j = 0; j < n + 1; j++)
{
for (int k = 0; k < N; k++)
{
X.at<double>(i, j) = X.at<double>(i, j) + pow(key_point[k].x, i + j);
}
}
}
//构造Y
Mat Y = Mat::zeros(n + 1, 1, CV_64FC1);
for (int i = 0; i < n + 1; i++)
{
for (int k = 0; k < N; k++)
{
Y.at<double>(i, 0) = Y.at<double>(i, 0) + pow(key_point[k].x, i) * key_point[k].y;
}
}
A = Mat::zeros(n + 1, 1, CV_64FC1);
//求解A
solve(X, Y, A, DECOMP_LU);
for (float x = top_y; x < writeImage.rows; x++)
{
double y = A.at<double>(0, 0) + A.at<double>(1, 0) * x +
A.at<double>(2, 0)*pow(x, 2) + A.at<double>(3, 0)*pow(x, 3);
poly_point.push_back(Point2f(y, x));
}
Point2f now, next;
vector<Point2f>::iterator it = poly_point.begin();
next = *it++;
while (it != poly_point.end())
{
now = next;
next = *it++;
line(writeImage, now, next, Scalar(255, 255, 0), 5, 16);
}
// cout << A << endl;
// cout << poly_point << endl;
return true;
}
//void RoadDetection::findSide(const Mat& inputImage)
//{
// bool left = true;
// //cout << inputImage.cols << " " << inputImage.rows << endl; //690 456
// for (int x = 0; x < inputImage.cols; ++x)
// {
// for (int y = inputImage.rows-1; y > inputImage.rows-10; --y)
// {
// if (left&&inputImage.at< uchar>(y, x) == 255)
// {
// left = false;
// left_x = x;
// }
// if (inputImage.at(y, x) == 255)
// {
// right_x = x;
// }
// //cout << (int)inputImage.at(x, y) << " ";
// }
// cout <
// }
// cout << left_x << " " << right_x << endl;
//}
void RoadDetection::findTop(vector<vector<Vec4i> > output)
{
top_y = writeImage.rows;
for (auto i : output[0])
{
if (top_y > (i[1] < i[3] ? i[1] : i[3]))
{
top_y = (i[1] < i[3] ? i[1] : i[3]);
}
}
for (auto i : output[1])
{
if (top_y > (i[1] < i[3] ? i[1] : i[3]))
{
top_y = (i[1] < i[3] ? i[1] : i[3]);
}
}
}
void RoadDetection::detection()
{
vector<Vec4i> lines;
vector<vector<Vec4i> > output(2),selectLines(2);
vector<Point> lane;
Mat midImage,tmpImage= readImage.clone();
Mat drawImage(readImage.size(), readImage.type(), Scalar(0,0,0));
Mat brightImage, colorImage, edgeImg;
//myShow("【原图】", readImage);
deNoise(readImage, midImage);
//myShow("【滤波】", midImage);
//CloseOperation(midImage, midImage);
//myShow("【闭运算】", midImage);
HistEqualize(midImage, brightImage);
//myShow("【直方图均衡化】", brightImage);
mask(midImage, midImage);
//myShow("【ROImidImage】", midImage);
mask(brightImage, brightImage);
//myShow("【ROI】", brightImage);
//Brightness(brightImage, brightImage);
//myShow("【亮度提取】", brightImage);
//colorThreshold(midImage, colorImage);
//myShow("【颜色阈值】", colorImage);
//addWeighted(brightImage, 1, colorImage, 1, 0.0, midImage);
//myShow("【特征提取】", midImage);
edgeDetector(midImage, edgeImg);
//myShow("【边缘检测】", midImage);
lines = houghLines(edgeImg);
//drawDetectedLines(tmpImage, lines, Scalar(0, 255, 0));
//myShow("lines", tmpImage);
lineSeparation(lines, output);
//drawDetectedLines(writeImage, output[0], Scalar(0, 255, 0));
//drawDetectedLines(writeImage, output[1], Scalar(0, 0, 255));
//
if (left_flag == 0 || right_flag == 0) {
if (canTh == 150) {
cout << "再次检测" << endl;
//表示检测未成功 降低cannny的阈值再试一下
canTh = 75;
edgeDetector(midImage, midImage);
//myShow("【边缘检测】", midImage);
lines = houghLines(midImage);
//drawDetectedLines(tmpImage, lines, Scalar(0, 255, 0));
//myShow("lines", tmpImage);
lineSeparation(lines, output);
drawDetectedLines(writeImage, output[0], Scalar(0, 255, 0));
drawDetectedLines(writeImage, output[1], Scalar(0, 0, 255));
myShow("final lines", writeImage);
}
}
if (left_flag == 0 || right_flag == 0) {
cout << "检测失败" << endl;
return;
}
//select_lines(output, selectLines);
//output[0]右边所有线的集合 output[1]左边所有线的集合 存的都是Vec4i
drawDetectedLines(tmpImage, output[0], Scalar(0, 255, 0));
drawDetectedLines(tmpImage, output[1], Scalar(0, 0, 255));
//myShow("lines", tmpImage);
//drawDetectedLines(tmpImage, lines, Scalar(0, 255, 0));
lane = regression(output, midImage);
/*if (predictTurn(lane[0].x, lane[2].x))
{
line(writeImage, lane[0], lane[1], Scalar(0, 255, 255), 5, 16);
line(writeImage, lane[2], lane[3], Scalar(0, 255, 255), 5, 16);
}
else
{
findTop(output);
polynomial_curve_fit(output[0],3);
polynomial_curve_fit(output[1], 3);
}*/
line(writeImage, lane[0], lane[1], Scalar(0, 255, 255), 5, 16);
line(writeImage, lane[2], lane[3], Scalar(0, 255, 255), 5, 16);
}
main.cpp
#include
#include
#include
#include
#include
#include "roadDetection.h"
using namespace std;
using namespace cv;
获取特定格式的文件名
//void getAllFiles(string path, vector& files, string format)
//{
// long hFile = 0;//文件句柄 64位下long 改为 intptr_t
// struct _finddata_t fileinfo;//文件信息
// string p;
// if ((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(), &fileinfo)) != -1) //文件存在
// {
// do
// {
// if ((fileinfo.attrib & _A_SUBDIR))//判断是否为文件夹
// {
// if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)//文件夹名中不含"."和".."
// {
// files.push_back(p.assign(path).append("\\").append(fileinfo.name)); //保存文件夹名
// getAllFiles(p.assign(path).append("\\").append(fileinfo.name), files, format); //递归遍历文件夹
// }
// }
// else
// {
// files.push_back(p.assign(path).append("\\").append(fileinfo.name));//如果不是文件夹,储存文件名
// }
// } while (_findnext(hFile, &fileinfo) == 0);
// _findclose(hFile);
// }
//}
//int main()
//{
// //vector files;
// //string filePath = "D:\\用户文件夹\\Documents\\Visual Studio 2017\\Projects\\道路检测\\道路检测\\road\\";
// //string format = ".jpg";
// //getAllFiles(filePath, files, format);
// //for (int i = 0; i < files.size(); i++)
// //{
// Mat readimage;
// string readStr = INPUT;
// string writeStr = OUTPUT;
//
// readimage = imread(readStr);
// if (!readimage.data) { printf("读取Image错误~! \n"); return -1; }
// imshow("原图", readimage);
//
// RoadDetection RoDetec(readimage);
// RoDetec.detection();
//
// Mat writeimage = RoDetec.result();
// imshow("检测图", writeimage);
// imwrite(writeStr, writeimage);
//
// waitKey(0);
}
//
// return 0;
//}
void loop(string readStr, string writeStr)
{
readStr = readStr;
writeStr = "result\\" + writeStr;
Mat readimage;
readimage = imread(readStr);
if (!readimage.data) { printf("读取Image错误~! \n"); return;}
//imshow(readStr, readimage);
RoadDetection RoDetec(readimage);
RoDetec.detection();
Mat writeimage = RoDetec.result();
//imwrite(writeStr, writeimage);
imshow(writeStr, writeimage);
}
int main()
{
string folder_path = "repos/test_lane/data/*.png";
vector<cv::String> file_names;
glob(folder_path, file_names);
cv::Mat img;
//cout << file_names.size() << endl;
for (int i = 0; i < file_names.size(); i++) {
clock_t s = clock();
loop(file_names[i], file_names[i]);
clock_t e = clock();
cout << double(e - s) << "ms" << endl;
waitKey(0);
}
//string str1 = "./data/7.png";
//loop(str1, str1);
//waitKey(0);
}