对画面进行裁剪可以有效滤除背景对车道线检测的影响,进行完裁剪后,考虑到车道线有明显的颜色特征,且与其他位置的颜色没有重合,考虑对地面进行颜色识别。主流的色彩空间有RGB、BGR、HSV等,经过测试,使用HSV颜色空间进行颜色提取最为有效。HSV采用色调(H),饱和度(S),明度(V)来表示颜色,其具有更平衡的色差感知,在实际应用中可以发现其对于颜色的识别更加精确。提取颜色之后,画面中可能存在一些噪声,为了保证阈值能够预留一定的空间,此处使用形态学方法对检测效果进行优化,对画面中的各个区块进行先腐蚀后膨胀的操作,即可过滤画面中存在的噪声。下图为初步进行颜色提取后得到的结果。
可以看到,右侧边线同为蓝色调,若想留出一定的阈值空间则需要使用其他方案将其去除,此处我们采用了类似于滑动窗格法进行优化,以实现对于车道线的精确提取。先从画面的底部进行处理,此处的车道线具有的信息最为可靠,从底部开始逐步向上进行处理,将底部识别到的车道线中点作为远端车道线的预期位置,将不在预期位置中的信息滤除,即可提取得到正确的车道线信息。
得到车道线信息后即可对其进行拟合,使用一次函数拟合即可得到车道线的趋势,适用于实际检测环境,若要得到车道线中点数组,可以使用三次函数进行拟合。
# -*- coding: utf-8 -*
import numpy as np
import cv2
import math
import time
import matplotlib
from skimage import morphology
cap = cv2.VideoCapture('1.mp4')
step = 35 #滑动窗格的高度
block = 200 #滑动窗格的宽度
height = 280 #裁剪的高度
while True:
start = time.time()
_ , frame = cap.read()
frame1 = frame
frame = frame[1080 - height:1080]
#dst = cv2.blur(frame,(5,5))
dst = cv2.GaussianBlur(frame,(5,5),0) #对图像进行第一次高斯滤波
#dst = cv2.medianBlur(frame,5)
hsv = cv2.cvtColor(dst,cv2.COLOR_BGR2HSV) #使用HSV颜色空间
lower_blue = np.array([81,79,77])#设置需要识别的车道线颜色的阈值
upper_blue = np.array([161,255,185])
lower_white = np.array([30,0,195])
upper_white = np.array([120,37,255])
#dark_blue = np.uint8([[[12,22,121]]])
#dark_blue = cv2.cvtColor(dark_blue,cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv,lower_blue,upper_blue) + cv2.inRange(hsv,lower_white,upper_white) #提取所需颜色
mask = morphology.erosion(mask,morphology.square(11)) #形态学方法滤除噪声
#cv2.imshow('mask1', mask)
for i in range(0, height, step): #滑动窗格法优化
mask1 = mask[height - (i + step):height - i]
nonzero1 = np.nonzero(mask1)
mid = np.median(nonzero1[1])
if (math.isnan(mid)):
continue
mid = int(mid)
#print(np.median(nonzero1[1]))
mask[height - (i + step):height - i, 0 : mid - block] = 0
mask[height - (i + step):height - i, mid + block : 1920] = 0
mask[height - (i + step * 2):height - (i + step), 0 : mid - block] = 0
mask[height - (i + step * 2):height - (i + step), mid + block : 1920] = 0
out = frame
nonzero = np.nonzero(mask[0: 240])
x = nonzero[0]
y = nonzero[1]
if (x != [] and y != []):
z1 = np.polyfit(x, y, 1)#用1次多项式拟合
p1 = np.poly1d(z1)
for t in range(x.min(), x.max()):
y_ = np.int(p1(t))
#print(y_)
cv2.circle(out, (y_, t), 1, (0, 0, 255), 1, 8, 0) #绘制拟合好的曲线
frame1[800:1080] = out
#res = cv2.bitwise_and(frame,frame,mask=mask)
cv2.imshow('frame',frame1)
cv2.imshow('mask', mask)
#cv2.imshow('res', res)
k = cv2.waitKey(5) & 0xff
#if k == 27:
# break
end = time.time()
seconds = end - start
print("Time taken : {0} seconds".format(seconds))
# 计算FPS,alculate frames per second
fps = 1 / seconds;
print("Estimated frames per second : {0}".format(fps))
cv2.destroyAllWindows()
cap.release()
Comments NOTHING