使用opencv3 检测车道线

参考博文ios

#include <iostream>
#include <list>
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace std;
using namespace cv;
int main(int argc, char **argv) {
    Mat img, gray, blur_img, edges, mask, masked_edges;
    img = imread("img.jpg",-1);
    if(img.empty())
	return -1;

    cvtColor(img, gray, cv::COLOR_BGR2GRAY);
    GaussianBlur(gray, blur_img, Size(5,5), 0);
    Canny(blur_img, edges, 100, 250);
    
    //ROI 
    mask = Mat::zeros(img.size(),CV_8UC1);
    vector<vector<Point> > contour;
    vector<Point> pts;
    pts.push_back(Point(0,img.rows));
    pts.push_back(Point(img.cols/2.0-20,img.rows*0.6));
    pts.push_back(Point(img.cols/2.0+20,img.rows*0.6));
    pts.push_back(Point(img.cols,img.rows));
    contour.push_back(pts);
    drawContours(mask,contour,0,Scalar::all(255),-1);
    edges.copyTo(masked_edges, mask);
    
    vector<Vec4i> lines, left_lines, right_lines;  // Vec4i -> lines[i][0-3]
    HoughLinesP(masked_edges, lines, 2, CV_PI/180, 30, 10, 30);  //lines' coordinate 
    vector<double> left_slope, right_slope;
    vector<Point2d> left_centers, right_centers;  //Point2d -> left_centers[i].x
    list<Vec4i> list_lines;     
    double slo;
    Point2d center;
    int i = 0;
    
    
    for(auto v:lines)   // vector -> list
	list_lines.push_back(v);
    
    for(auto iter = list_lines.begin(); iter != list_lines.end(); i++)  //list to erase 
    {
	slo = double((lines[i][3]-lines[i][1]))/double((lines[i][2]-lines[i][0])) ;  
	center = Point( double(lines[i][2]+lines[i][0])/2 , double(lines[i][3]+lines[i][1])/2 );

	if(fabs(slo)<0.35)     
	{
	    iter = list_lines.erase(iter);
	    continue;
	}
	if(slo > 0)
	{
	    right_lines.push_back(lines[i]);
	    right_centers.push_back(center);
	    right_slope.push_back(slo);
	}
	else
	{
	    left_lines.push_back(lines[i]);
	    left_centers.push_back(center);
	    left_slope.push_back(slo);
	}
	    
	*iter = lines[i];
	iter++;
    }
    
    //left to mean slope and center
    double left_len, total_left_len=0, total_left_slope=0;
    Point2d total_left_center(0,0);
    for(int i = 0; i< left_lines.size(); i++)
    {
	left_len = sqrt( (left_lines[i][2]-left_lines[i][0])*(left_lines[i][2]-left_lines[i][0]) + (left_lines[i][3]-left_lines[i][1])*(left_lines[i][3]-left_lines[i][1]) );
	total_left_slope = total_left_slope + left_len * left_slope[i];
	total_left_len = total_left_len + left_len;
	total_left_center = Point(total_left_center.x + left_len * left_centers[i].x , total_left_center.y + left_len * left_centers[i].y );
    }
    
    double mean_left_slope;
    Point2d mean_left_center;
    mean_left_slope = total_left_slope/ total_left_len;
    mean_left_center = Point( total_left_center.x/total_left_len, total_left_center.y/total_left_len);

    //right to mean slope and center
    double right_len, total_right_len=0, total_right_slope=0;
    Point2d total_right_center(0,0);
    for(int i = 0; i< right_lines.size(); i++)
    {
	right_len = sqrt( (right_lines[i][2]-right_lines[i][0])*(right_lines[i][2]-right_lines[i][0]) + (right_lines[i][3]-right_lines[i][1])*(right_lines[i][3]-right_lines[i][1]) );
	total_right_slope = total_right_slope + right_len * right_slope[i];
	total_right_len = total_right_len + right_len;
	total_right_center = Point(total_right_center.x + right_len * right_centers[i].x , total_right_center.y + right_len * right_centers[i].y );
    }
    
    double mean_right_slope;
    Point2d mean_right_center;
    mean_right_slope = total_right_slope/ total_right_len;
    mean_right_center = Point( total_right_center.x/total_right_len, total_right_center.y/total_right_len);
    
    double start_y = img.rows * 0.6;
    double end_y = img.rows;
    double left_start_x = (start_y - mean_left_center.y)/mean_left_slope + mean_left_center.x;
    double left_end_x = (end_y - mean_left_center.y)/mean_left_slope + mean_left_center.x;
    double right_start_x = (start_y - mean_right_center.y)/mean_right_slope + mean_right_center.x;
    double right_end_x = (end_y - mean_right_center.y)/mean_right_slope + mean_right_center.x;      
    
    line(img, Point(left_start_x, start_y), Point(left_end_x, end_y), Scalar(0,0,255), 3, 8);
    line(img, Point(right_start_x, start_y), Point(right_end_x, end_y), Scalar(0,0,255), 3, 8);
   
// vector<Vec4i> pro_lines; //list(after erase) -> vector
// for(auto v:list_lines)
// pro_lines.push_back(v);
    
// for(int i=0; i<pro_lines.size(); i++)
// {
// line(img, Point(pro_lines[i][0], pro_lines[i][1]),
// Point(pro_lines[i][2], pro_lines[i][3]) ,Scalar(255,0,0),3,8);
// }

    imshow("image", img);
    waitKey(0);
    return 0;
}

在这里插入图片描述