OpenCV - 车道检测,黄色和白色车道

OpenCV - Lane detetion, both yellow and white lanes

我有赛车游戏的道路照片。

我想检测黄色和白色车道。

如果我使用 RGB space,

def select_rgb_white_yellow(image): 
    # white color mask
    lower = np.uint8([123, 116, 116])
    upper = np.uint8([186, 172, 160])
    white_mask = cv2.inRange(image, lower, upper)
    # yellow color mask
    lower = np.uint8([134, 121, 100])
    upper = np.uint8([206, 155, 87])
    yellow_mask = cv2.inRange(image, lower, upper)
    # combine the mask
    mask = cv2.bitwise_or(white_mask, yellow_mask)
    masked = cv2.bitwise_and(image, image, mask = mask)
    return masked

我只有白色车道。
通过使用此代码,使用 HLS space 进行了一些微调。

def convert_hls(image):
    return cv2.cvtColor(image, cv2.COLOR_RGB2HLS)

然后,再次提取黄白线,

def select_white_yellow(image):
    converted = convert_hls(image)
    # white color mask
    lower = np.uint8([0, 0, 0])
    upper = np.uint8([0, 0, 255])
    white_mask = cv2.inRange(converted, lower, upper)
    # yellow color mask
    lower = np.uint8([ 10,   0, 100])
    upper = np.uint8([ 40, 255, 255])
    yellow_mask = cv2.inRange(converted, lower, upper)
    # combine the mask
    mask = cv2.bitwise_or(white_mask, yellow_mask)
    return cv2.bitwise_and(image, image, mask = mask)

然后它就再也检测不到白色车道了。有什么好的方法可以同时检测白色和黄色车道吗?



这是我找到的所有RGB颜色代码

Yellow
c2974A (194, 149, 74)
a07444 (160, 116, 68)
b38e55 (179, 142, 85)
867964 (134, 121, 100)
ce9b57 (206, 155, 87)
ce9853 (206, 152, 83)

white
b4a59d (180, 165, 157)
b9a99a (185, 169, 154)
baaca0 (186, 172, 160)
867e79 (134, 126, 121)
7b7474 (123, 116, 116)
827d7c (130, 125, 124)

扩展评论:这是一个 2 阶段方法的实现。花点时间看看中间的 images/masks 以完全理解发生的一切。

裁剪到感兴趣区域
您可以自动执行此操作,但我作弊并手动完成。裁剪过的天空区域很少有路面,我认为这是一个足够(目前)的简单解决方案。同样,我也切掉了右侧的 HUD 框,因为它们具有与道路相似的灰色并且会产生干扰。在它们上面画黑框更整洁,所以它们被排除在处理之外。

隔离路
将裁剪后的图像转换为 HSV 和 select 只有灰色值。去除一些噪声后,我使用 findContours 改进了蒙版以绘制凸包。如果性能有问题,您可以通过调整 close mask 步骤来跳过它。

选择行
使用蒙版,您可以创建仅路面的图像。您可以使用它进行分色,而不必担心 select 环境。我的结果并不完美,但我假设你有更大版本的图像,这样会得到更好的结果。

结果:

代码:

import cv2
import numpy as np 

# load image
image = cv2.imread('pw12b.jpg')
# crop image
h,w = image.shape[:2]
image = image[200:h-20,20:550]
# create hsv
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# set lower and upper color limits
low_val = (0,0,0)
high_val = (179,45,96)
# Threshold the HSV image 
mask = cv2.inRange(hsv, low_val,high_val)
# remove noise
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel=np.ones((8,8),dtype=np.uint8))
# close mask
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel=np.ones((20,20),dtype=np.uint8))

# improve mask by drawing the convexhull 
ret, contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
    hull = cv2.convexHull(cnt)
    cv2.drawContours(mask,[hull],0,(255), -1)
# erode mask a bit to migitate mask bleed of convexhull
mask = cv2.morphologyEx(mask, cv2.MORPH_ERODE, kernel=np.ones((5,5),dtype=np.uint8))

# remove this line, used to show intermediate result of masked road
road = cv2.bitwise_and(image, image,mask=mask)

# apply mask to hsv image
road_hsv = cv2.bitwise_and(hsv, hsv,mask=mask)
# set lower and upper color limits
low_val = (0,0,102)
high_val = (179,255,255)
# Threshold the HSV image 
mask2 = cv2.inRange(road_hsv, low_val,high_val)
# apply mask to original image
result = cv2.bitwise_and(image, image,mask=mask2)

#show image
cv2.imshow("Result", result)
cv2.imshow("Road", road)
cv2.imshow("Mask", mask)
cv2.imshow("Image", image)

cv2.waitKey(0)
cv2.destroyAllWindows()