Ask Your Question
1

Detection of hand-drawn lines

asked 2018-12-28 04:37:09 -0600

Spatial gravatar image

updated 2018-12-28 05:31:15 -0600

Hi,

I am trying to count lines shown in this image.

image description

After dilations I get this.

image description

import cv2
import math

img = cv2.imread('D:/Books/lines1.jpg', cv2.IMREAD_GRAYSCALE)


edges = cv2.Canny(img,50,150,apertureSize = 3)
cv2.imwrite('D:/Books/edges.jpg',edges)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))

dilated_Edges = cv2.dilate(edges, kernel, iterations=1)
cv2.imwrite("D:/Books/dilated_Edges.jpg", dilated_Edges)



lines = cv2.HoughLinesP(dilated_Edges,1,math.pi/180,15,minLineLength=100,maxLineGap=10)
for line in lines:
    x1,y1,x2,y2 = line[0]
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)
cv2.imwrite('D:/Books/correcthoughlines.jpg',img)
print( len(lines))

The image with lines detected is this.

image description

Even though it prints '6' I don't I understood how this works. I mean the parameters and how they have to be tweaked. So, for example, increasing maxLineGap prints 7 as the algorithm seems to include the last vertical line.

image description

The code I have fails for similar images like these.

image description image description

Can anyone guide ?

Thanks,

Mohan

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
2

answered 2018-12-28 09:42:34 -0600

updated 2018-12-29 17:53:40 -0600

after some morphologic operations you can find contours and count horizontal and vertical lines.

see the code below ( kernels are experimental and could be improved )

image description


image description

import cv2
import math

img = cv2.imread('e:/test/lines.jpg', cv2.IMREAD_GRAYSCALE)


ret,bw = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
cv2.imshow("bw", bw)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 2))
eroded_Edges = cv2.erode(bw, kernel, iterations=3)

dilated_Edges = cv2.dilate(eroded_Edges, kernel, iterations=2)

contours, hierarchy = cv2.findContours(dilated_Edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

print (len(contours) , " vertical lines")

cv2.imshow("vertical lines", eroded_Edges)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 5))
eroded_Edges = cv2.erode(bw, kernel, iterations=3)

contours, hierarchy = cv2.findContours(eroded_Edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

print (len(contours) , " horizontal lines")

cv2.imshow("horizontal lines", eroded_Edges)

cv2.waitKey()
edit flag offensive delete link more

Comments

Is this the way to print it ? Values aren't correct.

ret,bw = cv2.threshold(img,0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imshow("bw", bw)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 2))
dilated_Edges = cv2.dilate(bw, kernel, iterations=3)

eroded_Edges = cv2.erode(dilated_Edges, kernel, iterations=2)
lines = cv2.HoughLinesP(eroded_Edges,1,math.pi/180,150,minLineLength=100,maxLineGap=50)
if lines != None:
    print (lines.shape)
cv2.imshow("vertical lines", eroded_Edges)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 5))
dilated_Edges = cv2.dilate(bw, kernel, iterations=3)
lines = cv2.HoughLinesP(dilated_Edges,1,math.pi/180,150,minLineLength=100,maxLineGap=50)
if lines != None:
   print (lines.shape)
Spatial gravatar imageSpatial ( 2018-12-29 02:07:10 -0600 )edit

see the updated answer

sturkmen gravatar imagesturkmen ( 2018-12-29 17:54:15 -0600 )edit

Appreciate your help. I have to test this further.

Spatial gravatar imageSpatial ( 2018-12-29 22:44:55 -0600 )edit

Works with slight syntax changes.

im2, contours, hierarchy = cv2.findContours(dilated_Edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

print (len(contours) , " horizontal lines")


im2, contours, hierarchy = cv2.findContours(eroded_Edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

print (len(contours) , " vertical lines")
Spatial gravatar imageSpatial ( 2018-12-29 22:55:54 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2018-12-28 04:35:19 -0600

Seen: 678 times

Last updated: Dec 29 '18