6
votes

So I'm trying to obtain hough lines on a chessboard, but the algorithm results in only one line being detected. I'm using python 2.7 and opencv 3.0. Here's the code:

def applyHoughLineTransform():
    image1 = cv2.imread('pictures/board1.png',0)
    image2 = cv2.imread('pictures/board2.png',0)
    image3 = cv2.imread('pictures/board3.png')
    image4 = cv2.imread('pictures/board4.png')

    lines1 = cv2.HoughLines(image1,1,math.pi/180.0,5)
    lines2 = cv2.HoughLines(image2,1,math.pi/180.0,5)

    lines1 = lines1[0]
    lines2 = lines2[0]

    for rho,theta in lines1:
        print ('Rho and theta:',rho,theta)
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a*rho
        y0 = b*rho
        x1 = int(x0 + 1000*(-b))
        y1 = int(y0 + 1000*(a))
        x2 = int(x0 - 1000*(-b))
        y2 = int(y0 - 1000*(a))

        print (x1,y1)
        print (x2,y2)

        cv2.line(image3,(x1,y1),(x2,y2),(0,0,255),2)

    for rho,theta in lines2:
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a*rho
        y0 = b*rho
        x1 = int(x0 + 1000*(-b))
        y1 = int(y0 + 1000*(a))
        x2 = int(x0 - 1000*(-b))
        y2 = int(y0 - 1000*(a))

        cv2.line(image4,(x1,y1),(x2,y2),(0,0,255),2)

    cv2.imwrite('pictures/board1.png',image1)
    cv2.imwrite('pictures/board2.png',image2)

    cv2.imshow('hough line 1',image3)
    cv2.imshow('hough line 2',image4)

Here's the canny edge image on which i perform the hough line algorithm: enter image description here

And here are the results: enter image description here

As you can see, pretty lame. The canny algorithm seems to be providing really nice edges to operate on. I'm not entirely sure what I'm doing wrong. I imagine it has something to do with the arguments inputted into the houghLines function. If someone could point me in the right direction (or fix my problem entirely :) ) I would greatly appreciate it. Here's a link to the tutorial site I'm using: http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_houghlines/py_houghlines.html

3
I don't see a Canny() in your code..a-Jays
it's in a different function, and everything is in my main loop. The canny image I operate on is above the hough as stated in my postuser1243

3 Answers

14
votes

OPENCV 3.1.0

After checking the example from the package This is what you should use to get it right in Opencv 3.0.0 +

import cv2
import numpy as np
import math

image1 = cv2.imread('img.png')
gray=cv2.cvtColor(image1,cv2.COLOR_BGR2GRAY)
dst = cv2.Canny(gray, 50, 200)

lines= cv2.HoughLines(dst, 1, math.pi/180.0, 100, np.array([]), 0, 0)
#lines1 = cv2.HoughLines(image1,1,math.pi/180.0,5)
#lines2 = cv2.HoughLines(image2,1,math.pi/180.0,5)

#lines1 = lines1[0]
#lines2 = lines2[0]

a,b,c = lines.shape
for i in range(a):
    rho = lines[i][0][0]
    theta = lines[i][0][1]
    a = math.cos(theta)
    b = math.sin(theta)
    x0, y0 = a*rho, b*rho
    pt1 = ( int(x0+1000*(-b)), int(y0+1000*(a)) )
    pt2 = ( int(x0-1000*(-b)), int(y0-1000*(a)) )
    cv2.line(image1, pt1, pt2, (0, 0, 255), 2, cv2.LINE_AA)


cv2.imshow('image1',image1)
cv2.waitKey(0)
cv2.destoryAllWindows(0)

OUTPUT

enter image description here

6
votes

The fix to this issue, was to switch from opencv 3.0 to 2.4. Now I get all the lines I want. Lesson learned... it's in beta for a reason! Here are the results: enter image description here

3
votes

I had the same issue with OpenCV 3.4. The culprit is in the numpy array lines:

[[[  7.99000000e+02   1.57079637e+00]] 
 [[  9.39000000e+02   1.57079637e+00]]    
 [[  1.57100000e+03   1.57079637e+00]]    
 [[  6.68000000e+02   1.57079637e+00]]    
 [[  5.46000000e+02   1.57079637e+00]]    
 [[  1.42700000e+03   1.57079637e+00]]
 ...
 [[  1.49100000e+03   1.57079637e+00]]]

Notice this is a 3D array, while the example code treats it as a 2D array. The fix is simply to extract rho and theta from the 3D array (only the first 2 lines are changed):

for line in lines:
    rho, theta = line[0]
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0 + 1000*(-b))
    y1 = int(y0 + 1000*(a))
    x2 = int(x0 - 1000*(-b))
    y2 = int(y0 - 1000*(a))

    cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)