使用opencv查找道路边缘

时间:2016-07-07 06:45:56

标签: python opencv image-processing computer-vision

我有兴趣找到路的边缘。输出图像应仅标记边缘。 这是我输入的图像之一:

enter image description here

但是输出中的边缘要么扭曲,要么有很多噪音。 这是它的输出:

output

我尝试过应用分水岭算法,但它没有正确检测道路。

这是我的代码:

import cv2
import numpy as np

img = cv2.imread('road2.jpg',0)

ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(thresh1,kernel,iterations = 1)
#Removing noise from image
blur = cv2.blur(img,(5,5))
#finding edges using edge detection
edges = cv2.Canny(blur, 100 ,200)


laplacian = cv2.Laplacian(edges, cv2.CV_8UC1)
sobely = cv2.Sobel(laplacian,cv2.CV_8UC1, 0, 1, ksize=5)
im2, contours, hierarchy = cv2.findContours(sobely,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

frame = cv2.drawContours(im2, contours, -1, (255,0,0), 3)
cv2.imshow('window',frame)

cv2.waitKey(0)
cv2.destroyAllWindows()

inoder应该做什么来仅标记边缘。我只想要输出中的边缘,因为我后来需要这些边缘来找到道路的中间车道。

1 个答案:

答案 0 :(得分:0)

结果可见here。不完美,但我能做到最好。取自here

的想法

该代码适用于此图像,假设:

如果道路上没有汽车,则两个标记(左侧和右侧)将在地平线上的消失点处相遇并形成三角形。所以,我只保留可以用三角形近似的最大轮廓。

import cv2
import numpy as np

img = cv2.imread('road2.jpg',0)

ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(thresh1,kernel,iterations = 1)
#Removing noise from image
blur = cv2.blur(img,(5,5))
#finding edges using edge detection
edges = cv2.Canny(blur, 100 ,200)


laplacian = cv2.Laplacian(edges, cv2.CV_8UC1)
sobely = cv2.Sobel(laplacian,cv2.CV_8UC1, 0, 1, ksize=5)

# Do a dilation and erosion to accentuate the triangle shape
dilated = cv2.dilate(sobely,kernel,iterations = 1)
erosion = cv2.erode(dilated,kernel,iterations = 1)

im2, contours, hierarchy =  cv2.findContours(erosion,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

#keep 10 largest contours
cnts = sorted(contours, key = cv2.contourArea, reverse = True)[:10]
screenCnt = None

for c in cnts:
    # approximate the contour
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.05 * peri, True)
    # if our approximated contour has three points, then
    # it must be the road markings
    if len(approx) == 3:
        screenCnt = approx
        break
cv2.drawContours(img, [screenCnt], -1, (0, 255, 0), 3)
cv2.imshow("Road markings", img)
cv2.waitKey(0)