Opencv-Python处理车道线检测

1.导入

我们先要找一张图片,对其进行检测.

import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
import math
# 读入图像
img = cv2.imread('lu.jpg',3)

Python opencv 车道线 opencv识别车道线_Python opencv 车道线

2.Canny边缘检测

为了突出车道线,我们对图像做边缘处理.“边缘”就是图像中明暗交替较为明显的区域.车道线通常为白色或黄色,地面通常为灰色或黑色,因此车道线的边缘处会有很明显的明暗交替.
以Canny算法为例,选取特定的阈值后,对灰度图像进行处理,即可得到的边缘提取的效果图.

# canny边缘检测
edges = cv2.Canny(img,150,350)
# 显示图像
image1 = Image.fromarray(edges.astype('uint8'))
display(image1)
# 计算图像高度的一半
pic_height = img.shape[0]//2

Python opencv 车道线 opencv识别车道线_Image_02

3.霍夫直线检测

# 参数有输入的图像,像素精度,弧度单位,最小点集,最小长度,最大间隔
lines = cv2.HoughLinesP(edges, 1,np.pi/360,10,minLineLength=100, maxLineGap=20)

``
cv2.HoughLinesP()函数原型:
HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None)

image: 必须是二值图像,推荐使用canny边缘检测的结果图像;
rho: 线段以像素为单位的距离精度,double类型的,推荐用1.0
theta: 线段以弧度为单位的角度精度,推荐用numpy.pi/180
threshod: 累加平面的阈值参数,int类型,超过设定阈值才被检测出线段,值越大,基本上意味着检出的线段越长,检出的线段个数越少。根据情况推荐先用100试试
lines:这个参数的意义未知,发现不同的lines对结果没影响,但是不要忽略了它的存在
minLineLength:线段以像素为单位的最小长度,根据应用场景设置
maxLineGap:同一方向上两条线段判定为一条线段的最大允许间隔(断裂),超过了设定值,则把两条线段当成一条线段,值越大,允许线段上的断裂越大,越有可能检出潜在的直线段 

4.计算线段中点

点坐标(x, y)中,x代表图片的列,y代表图片的行
所以如果想在图片中的位置(10, 0) 和 位置(0, 100)之间划线,则正确的调用语句为:
1 import cv2 as cv
2 #在(10, 0)和(0, 100)之间画条直线,直线的颜色为绿色
我们需要求出多余线段的中点,只留图片一半的下半部分.
线段中点坐标公式 X=(x1+x2)/2,Y=(y1+y2)/2

length = []
filter_index_list = []
# 循环每个线段
for i in range(lines.shape[0]):
    # 解析每个线段的端点坐标
    for x1, y1, x2, y2 in lines[i]:
        # 计算中点坐标
        center_x = int((x1+x2)/2)
        center_y = int((y1+y2)/2)
        # 过滤掉在图像上半部分的坐标
        if(center_y > pic_height):
            # 画出符合条件的线段
            cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 1)
            # 统计个数
            filter_index_list.append((x1, y1,x2, y2))

5.显示结果

image1 = Image.fromarray(img.astype('uint8'))
display(image1)

Python opencv 车道线 opencv识别车道线_Python opencv 车道线_03