36

I am having difficulty finding the lines on a chessboard in this image using HoughLinesP with OpenCV in Python.

In an attempt to understand the parameters of HoughLinesP, I have come up with the following code:

import numpy as np
import cv2
from matplotlib import pyplot as plt
from matplotlib import image as image

I = image.imread('chess.jpg') 
G = cv2.cvtColor(I, cv2.COLOR_BGR2GRAY)

# Canny Edge Detection:
Threshold1 = 150;
Threshold2 = 350;
FilterSize = 5
E = cv2.Canny(G, Threshold1, Threshold2, FilterSize)

Rres = 1
Thetares = 1*np.pi/180
Threshold = 1
minLineLength = 1
maxLineGap = 100
lines = cv2.HoughLinesP(E,Rres,Thetares,Threshold,minLineLength,maxLineGap)
N = lines.shape[0]
for i in range(N):
    x1 = lines[i][0][0]
    y1 = lines[i][0][1]    
    x2 = lines[i][0][2]
    y2 = lines[i][0][3]    
    cv2.line(I,(x1,y1),(x2,y2),(255,0,0),2)

plt.figure(),plt.imshow(I),plt.title('Hough Lines'),plt.axis('off')
plt.show()

The problem I am having is that this picks up only one line. If I reduce the maxLineGap to 1, it picks up thousands.

I understand why this might be but how do I pick a suitable set of parameters to get all these co-linear lines to merge? Am I missing something?

I would like to keep the code simple as I am using it as an example of this function in action.

Thanks in advance for any help!

Update: This works perfectly with HoughLines.

And there doesn't seem to be edge detection issues as Canny is working just fine.

However, I still need to get HoughLinesP to work. Any ideas??

Images here: Results

Jane Courtney
  • 1,400
  • 1
  • 9
  • 10

4 Answers4

94

Ok, I finally found the problem and thought I would share the solution for anyone else driven nuts by this. The issue is that in the HoughLinesP function, there is an extra parameter, "lines" which is redundant because the output of the function is the same:

cv2.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]])

This is causing issues with the parameters as they are read in the wrong order. To avoid confusion with the order of the parameters, the simplest solution is to specify them inside the function like so:

lines = cv2.HoughLinesP(E,rho = 1,theta = 1*np.pi/180,threshold = 100,minLineLength = 100,maxLineGap = 50)

This totally fixed my problem and I hope it will help others.

Jane Courtney
  • 1,400
  • 1
  • 9
  • 10
  • 7
    The [OpenCV tutorial](https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_houghlines/py_houghlines.html) on this doesn't clearly clarify this and up to this date actually makes the same mistake. Thank you for pointing this out. – Sebastian Mar 24 '18 at 22:40
6
  • edges: Output of the edge detector.
  • lines: A vector to store the coordinates of the start and end of the line.
  • rho: The resolution parameter \rho in pixels.
  • theta: The resolution of the parameter \theta in radians.
  • threshold: The minimum number of intersecting points to detect a line.

Sample application

import cv2
import numpy as np

img = cv2.imread('sudoku.png', cv2.IMREAD_COLOR)
# Convert the image to gray-scale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Find the edges in the image using canny detector
edges = cv2.Canny(gray, 50, 200)
# Detect points that form a line
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength=10, maxLineGap=250)
# Draw lines on the image
for line in lines:
    x1, y1, x2, y2 = line[0]
    cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), 3)

# Show result
img = cv2.resize(img, dsize=(600, 600))
cv2.imshow("Result Image", img)

if cv2.waitKey(0) & 0xff == 27:  
    cv2.destroyAllWindows()

enter image description here

Furkan Gulsen
  • 1,384
  • 2
  • 12
  • 24
3

cv2.HoughLinesP(image,rho, theta, threshold, np.array ([ ]), minLineLength=xx, maxLineGap=xx)

This will also work.

Sangha
  • 61
  • 2
-1

It is not HoughLinesP issue, using that method will only get all the lines detected in the picture and return to you.

To be able to get the lines you want,you will need to smooth the image before you use the method. However if you smooth too much, there won't be any edges for HoughLinesP to detect.

You can know more about Smoothing Effects of OpenCV here.

Meaniegy
  • 62
  • 1
  • 7
  • Thanks for getting back. There doesn't seem to be any issue with smoothing as: (a) it works perfectly for HoughLines, (2) The results from the Canny function are lovely (if I do say so myself!) and (d) Canny Edge Detection incorporates smoothing anyway. Any other ideas? Help! – Jane Courtney Feb 29 '16 at 15:21
  • Smoothing will remove background noises of the image. Canny does not smooth. Smoothing "blurs" the image which will provide lesser edges after edge detection (canny). – Meaniegy Mar 01 '16 at 01:35
  • So I gave you the benefit of the doubt and tried out smoothing. I also checked the Canny function code to see if it does smooth as the algorithm suggests it should. (a) Smoothing did not fix the problem, just reduced the number of edges (but I'm happy with the number of edges) and (b) the Canny code does indeed include smoothing as it should so an extra smoothing step is redundant. Thanks again for your help but any other ideas? – Jane Courtney Mar 04 '16 at 11:44