I want to detect the zebra crossing lines. I have tried to find out the co-ordinates of zebra crossing line in the image using contour but it gives the output for the distinct white boxes (only white lines in the zebra crossing). But I need the co-ordinates of the entire zebra crossing.
Please let me know the way to group the contours or suggest me another method to detect zebra crossing.
Input image
Output image obtained
Expected output
import cv2
import numpy as np
image = cv2.imread('d.jpg',-1)
paper = cv2.resize(image,(500,500))
ret, thresh_gray = cv2.threshold(cv2.cvtColor(paper, cv2.COLOR_BGR2GRAY),
200, 255, cv2.THRESH_BINARY)
image, contours, hier = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for c in contours:
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
# convert all coordinates floating point values to int
box = np.int0(box)
cv2.drawContours(paper, [box], 0, (0, 255, 0),1)
cv2.imshow('paper', paper)
cv2.imwrite('paper.jpg',paper)
cv2.waitKey(0)
You can closing morphological operation for closing the gaps.
I cat suggest the following stages:
thresh_gray. Here is a working code sample:
import cv2
import numpy as np
image = cv2.imread('d.jpg', -1)
paper = cv2.resize(image, (500,500))
ret, thresh_gray = cv2.threshold(cv2.cvtColor(paper, cv2.COLOR_BGR2GRAY), 200, 255, cv2.THRESH_BINARY)
image, contours, hier = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# Erase small contours, and contours which small aspect ratio (close to a square)
for c in contours:
area = cv2.contourArea(c)
# Fill very small contours with zero (erase small contours).
if area < 10:
cv2.fillPoly(thresh_gray, pts=[c], color=0)
continue
# https://stackoverflow.com/questions/52247821/find-width-and-height-of-rotatedrect
rect = cv2.minAreaRect(c)
(x, y), (w, h), angle = rect
aspect_ratio = max(w, h) / min(w, h)
# Assume zebra line must be long and narrow (long part must be at lease 1.5 times the narrow part).
if (aspect_ratio < 1.5):
cv2.fillPoly(thresh_gray, pts=[c], color=0)
continue
# Use "close" morphological operation to close the gaps between contours
# https://stackoverflow.com/questions/18339988/implementing-imcloseim-se-in-opencv
thresh_gray = cv2.morphologyEx(thresh_gray, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (51,51)));
# Find contours in thresh_gray after closing the gaps
image, contours, hier = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for c in contours:
area = cv2.contourArea(c)
# Small contours are ignored.
if area < 500:
cv2.fillPoly(thresh_gray, pts=[c], color=0)
continue
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
# convert all coordinates floating point values to int
box = np.int0(box)
cv2.drawContours(paper, [box], 0, (0, 255, 0),1)
cv2.imshow('paper', paper)
cv2.imwrite('paper.jpg', paper)
cv2.waitKey(0)
cv2.destroyAllWindows()
thresh_gray before erasing small and squared contours:
thresh_gray after erasing small and squared contours:
thresh_gray after close operation:
Final result:

Remark:
I have some doubts about the benefit of using morphological operation for closing the gaps.
It might be better using a smart logic based on geometry instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With