How to detect lines in OpenCV?

Viewed 123638

I am trying to detect lines in parking as shown below.

Empty parking lot

What I hope to get is the clear lines and (x,y) position in the crossed line. However, the result is not very promising.

Parking lot with Hough Lines drawn

I guess it is due to two main reasons:

  1. Some lines are very broken or missing. Even human eyes can clearly identify them. Even though HoughLine can help to connect some missing lines, since HoughLine sometimes would connect unnecessary lines together, I 'd rather to do it manually.

  2. There are some repeated lines.

The general pipeline for the work is shown as below:

1. Select some specific colors (white or yellow)

import cv2
import numpy as np
import matplotlib
from matplotlib.pyplot import imshow
from matplotlib import pyplot as plt

# white color mask
img = cv2.imread(filein)
#converted = convert_hls(img)
image = cv2.cvtColor(img,cv2.COLOR_BGR2HLS)
lower = np.uint8([0, 200, 0])
upper = np.uint8([255, 255, 255])
white_mask = cv2.inRange(image, lower, upper)
# yellow color mask
lower = np.uint8([10, 0,   100])
upper = np.uint8([40, 255, 255])
yellow_mask = cv2.inRange(image, lower, upper)
# combine the mask
mask = cv2.bitwise_or(white_mask, yellow_mask)
result = img.copy()
cv2.imshow("mask",mask) 

Binary image

2. Repeat the dilation and erosion until the image can not be changed (reference )

height,width = mask.shape
skel = np.zeros([height,width],dtype=np.uint8)      #[height,width,3]
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3))
temp_nonzero = np.count_nonzero(mask)
while(np.count_nonzero(mask) != 0 ):
    eroded = cv2.erode(mask,kernel)
    cv2.imshow("eroded",eroded)   
    temp = cv2.dilate(eroded,kernel)
    cv2.imshow("dilate",temp)
    temp = cv2.subtract(mask,temp)
    skel = cv2.bitwise_or(skel,temp)
    mask = eroded.copy()
 
cv2.imshow("skel",skel)
#cv2.waitKey(0)

 After the erosion and dialation

3. Apply the canny to filter the lines and use HoughLinesP to get the lines

edges = cv2.Canny(skel, 50, 150)
cv2.imshow("edges",edges)
lines = cv2.HoughLinesP(edges,1,np.pi/180,40,minLineLength=30,maxLineGap=30)
i = 0
for x1,y1,x2,y2 in lines[0]:
    i+=1
    cv2.line(result,(x1,y1),(x2,y2),(255,0,0),1)
print i

cv2.imshow("res",result)
cv2.waitKey(0)

After Canny

I wonder why after the first step of selecting certain color, the lines are broken and with noises. I would think in this step we should do something to make the broken line a complete, less noisy line. And then try to apply something to do the Canny and Hough lines. Any ideas?

5 Answers

I am beginner. I got something which may be helpful for this question.

A simple way to detect the lines in image.

Output:

output

below is code performed in google colab

import cv2
import numpy as np
from google.colab.patches import cv2_imshow
!wget  https://i.stack.imgur.com/sDQLM.png
#read image 
image = cv2.imread( "/content/sDQLM.png")

#convert to gray
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

#performing binary thresholding
kernel_size = 3
ret,thresh = cv2.threshold(gray,200,255,cv2.THRESH_BINARY)  

#finding contours 
cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

#drawing Contours
radius =2
color = (30,255,50)
cv2.drawContours(image, cnts, -1,color , radius)
# cv2.imshow(image) commented as colab don't support cv2.imshow()
cv2_imshow(image)
# cv2.waitKey()

Related