OpenCV实战——车道检测

OpenCV图像处理通常步骤:web

  • BGR变Gray,节省运算时间
  • 滤波处理(模糊图像,去噪点)
  • 边缘检测
  • ROI提取
  • 直线检测,hough变化+最小二乘法

在这里插入图片描述
在这里插入图片描述

import cv2
import numpy as np


class lane_detection():
    def __init__(self,image):
        self.image=image

    def process(self):
    	#滤波处理,去除噪声,平滑图像
        blur=cv2.GaussianBlur(self.image,(5,5),1)
        #边缘检测,Canny算法
        edge=cv2.Canny(blur,180,255)
        return edge

    def roi(self):
        edge=self.process()
        print(edge.shape[:2])
        rows,cols=edge.shape[:2]
        mask=np.zeros_like(edge)
        #梯形四点坐标
        shape=np.array([[(0,rows),((int)(cols/3)+100,(int)(rows*2/3)-30),((int)(2*cols/3)-100,(int)(rows*2/3)-30),(cols,rows)]])
        cv2.fillPoly(mask,shape,255)
        masked_img=cv2.bitwise_and(mask,edge)
        return masked_img

    def hough(self):
        masked_img=self.roi()
        left,right=[],[]
        rows,cols=masked_img.shape[:2]
        #houghP算法,提取线段两端点坐标
        lines=cv2.HoughLinesP(masked_img,1,np.pi/180,50,minLineLength=50,maxLineGap=20)
        print(len(lines))
        #提取左右两车道线段的集合,并分类
        for line in lines:
            for x1,y1,x2,y2 in line:
                if((y2-y1)/(x2-x1)>0):
                    left.append(line)
                else:
                    right.append(line)
        #提取左右两车道的坐标,并最小二乘法拟合
        left_points=[(x1,y1) for line in left for x1,y1,x2,y2 in line]
        left_points=left_points+[(x2,y2) for line in left for x1,y1,x2,y2 in line]
        right_points=[(x1,y1) for line in right for x1,y1,x2,y2 in line]
        right_points=right_points+[(x2,y2) for line in right for x1,y1,x2,y2 in line]

        print(len(left_points))
        print(len(right_points))
        left_x=[p[0] for p in left_points]
        left_y=[p[1] for p in left_points]
        right_x=[p[0] for p in right_points]
        right_y=[p[1] for p in right_points]
        fit_left=np.polyfit(left_y,left_x,1)
        fit_right=np.polyfit(right_y,right_x,1)
        left_fn=np.poly1d(fit_left)
        right_fn=np.poly1d(fit_right)
        print(left_fn)
        print(right_fn)
        left_x_min=(int)(left_fn(rows*2/3))
        left_x_max=(int)(left_fn(rows))
        print(left_x_min)
        print(left_x_max)
        right_x_min=(int)(right_fn(rows*2/3))
        right_x_max=(int)(right_fn(rows))
        print(right_x_min)
        print(right_x_max)
        lane=np.array([[(left_x_min,(int)(rows*2/3)),(left_x_max,rows),(right_x_max,rows),(right_x_min,(int)(rows*2/3))]])
        return lane



if __name__=='__main__':
    image=cv2.imread('lane.jpg',0)
    ld=lane_detection(image)
    shape=ld.hough()
    image=cv2.imread('lane.jpg',1)
    cv2.fillPoly(image,shape,(0,255,0))
    cv2.imshow('lane',image)
    cv2.imwrite('image2.jpg',image)
    cv2.waitKey(0)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述