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

时间:2019-04-28 15:23:08

标签: python opencv machine-learning computer-vision object-detection

我有赛车游戏中的公路照片。 enter image description here

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

如果我使用RGB空间,

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

enter image description here

我只有白道。
因此,使用此代码对HLS空间进行了一些调整。

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

enter image description here

然后,再次提取黄色和白色车道,

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)

enter image description here

然后它将无法再检测到白色车道。是否有检测白色和黄色车道的好方法?



这是我发现的所有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)

1 个答案:

答案 0 :(得分:1)

扩展评论:这是一个两阶段方法的实现。花一些时间看一下中间的图像/遮罩,以完全了解发生的一切。

裁剪到感兴趣的区域
您可以自动执行此操作,但是我作了一些欺骗并手动完成了操作。修剪过的天空区域几乎不会有路面,这是一个简单的解决方案,足以满足(目前)我想。同样,我也切掉了右侧的HUD框,因为它们具有与道路相似的灰色并且受到干扰。在它们上方绘制黑匣子更为整齐,因此将它们排除在处理之外。

隔离道路
将裁剪后的图像转换为HSV,仅选择灰色值。经过一些噪声消除后,我使用findContours绘制了凸包来改进了蒙版。如果性能是一个问题,则可以通过调整close mask步骤来跳过它。

选择行
使用遮罩可以创建仅路面的图像。您可以使用它进行分色,而不必担心选择周围环境。我的结果并不完美,但我认为您使用的图像版本较大,可以提供更好的结果。

结果: enter image description here

代码:

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()