Ask Your Question

Corners and lines detection in hand drawn pictures in Python

asked 2013-12-16 12:50:53 -0500

Francesco Sgaramella gravatar image

I'm working on a project and at some point I have to detect corners and lines in a hand drawn picture. I am doing the work in Python but the result I get is not that good.

The code I wrote is the following:

import sys
from math import sin, cos, sqrt, pi
import cv
src = cv.LoadImage('draw.jpg')
cv.NamedWindow("Source", 1)
cv.NamedWindow("Result", 1)
dst = cv.CreateImage(cv.GetSize(src), 8, 1)
color_dst = cv.CreateImage(cv.GetSize(src), 8, 3)
storage = cv.CreateMemStorage(0)
lines = 0
cv.Canny(src, dst, 1.0, 4.0, aperture_size=3)
cv.CvtColor(dst, color_dst, cv.CV_GRAY2BGR)
lines = cv.HoughLines2(dst, storage, cv.CV_HOUGH_PROBABILISTIC, 1, pi / 180, 10, 0, 10)
for line in lines:
    cv.Line(color_dst, line[0], line[1], cv.CV_RGB(0, 255, 0), 2, 8)
cornerMap = cv.CreateMat(dst.height, dst.width, cv.CV_32FC1)
for y in range(0,dst.height):
    for x in range (0, dst.width):
        harris = cv.Get2D(cornerMap, y, x)
        if harris[0] >10e-06:
            cv.Circle(color_dst, (x,y),2,cv.RGB(115,0,25))
cv.ShowImage("Source", src)
cv.ShowImage("Hough", color_dst)
cv.SaveImage("draw_det.png", color_dst)

The input picture can be seen here:

link text

While the resultant picture can be seen here:

link text

The result is not what I am expecting. What I want as output is to see the corner points detected in red and the lines connecting them in green. While what I get is something that does not make sense by looking at the pictures. What am I doing wrong?

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2013-12-16 16:35:45 -0500

Guanta gravatar image

First of all: don't use the old python interface, the cv2-interace is much cooler since you can use the mighty numpy-arrays --> i.e. use cv2 instead of cv.

You don't draw the lines in a correct way, thus they don't show up. For the Harris-corner-detector you just don't use the correct parameters, furthermore as suggested in the documentation a non-maximum suppression step should be used, to remove too close corners.

My solution, still not perfect though:

import cv2
import numpy as np

img = cv2.imread('draw.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)
edges = cv2.Canny(img, 50, 200)

# find lines
lines = cv2.HoughLinesP(np.copy(edges), 1, np.pi/180.0, 10, 0, 10)
# draw found lines        
img_dst = cv2.cvtColor(img,
for line in lines[0]:
    cv2.line(img_dst, (line[0], line[1]), (line[2], line[3]), (0,255,0), 2)

# find corners
dst = cv2.cornerHarris(img, 15, 5, 0.04)
# non-maximum suppression via dilation
kernel = np.ones((10,10))
max_dst = cv2.dilate(dst, kernel)   
dst = dst * (dst == max_dst)
# sort points by strength, find their positions and take 5 highest ones
sortIdx = np.argsort(dst.flatten())[::-1][:5]
# draw them
w = img.shape[1]
for idx in sortIdx:, (idx % w, idx / w) , 3, (0,0,255), -1)


image description

For the lines I just took your Hough-lines values, guess you could find better ones. Furthermore, Canny() produces two edges at each side of the lines which also results in two found lines, maybe other Canny-Parameters will work here better, too. For cornerHarris, I just draw the 5 most "corner-like" pixels according to the strength returned. However note that they are not sub-pixel accurate (maybe they could be refined w. cv2.cornerSubPix()).

edit flag offensive delete link more



Thank you so much! What you just give me is a great starting point! I will check the subPixel and the Canny. Thanks again! I will update the post as soon as I get something more. Could be helpful for others.

Francesco Sgaramella gravatar imageFrancesco Sgaramella ( 2013-12-17 03:42:07 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower


Asked: 2013-12-16 12:50:53 -0500

Seen: 3,472 times

Last updated: Dec 16 '13