How do I get HoughLines to recognize the rest of the lines in this picture?

5.6k views Asked by At

In the image below, you can see that I'm able to recognize the horizontal lines really well but the vertical ones aren't coming out so great. In particular, none of the middle lines of the grids are being seen and the side lines are being overdrawn (i.e. connected to each other).

Here's the code that created it:

img = cv2.imread('./p6.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
threshhold, threshhold_img = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
edges = cv2.Canny(threshhold_img, 150, 200, 3, 5)
lines = cv2.HoughLinesP(edges,1,np.pi/180,500, minLineLength = 600, maxLineGap = 75)[0].tolist()

for x1,y1,x2,y2 in lines:
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),1)

When I've adjusted the different parameters, I end up with situations like the one where the very middle vertical line (the one ending just before JEXXY in the table) extends from the bottom through to the top of the third grid. Unless I relax the params so much that almost every line is drawn in, including ones representing the yi, er, san at the top of the first three grids, I cannot get the code to see the middle verticals defining the grid interiors.

How can I fix this?

Image with hough lines drawn in

* Updated to use THRESH_BINARY_INV without canny *

img = cv2.imread('./p6.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
threshhold, threshhold_img = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV)
lines = cv2.HoughLinesP(edges,1,np.pi/180,500, minLineLength = 600, maxLineGap = 75)[0].tolist()

for x1,y1,x2,y2 in lines:
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),1)

Intermediate picture for threshold_img using THRESH_BINARY_INV

After doing THRESH_BINARY_INV, this is the lines output

* Update: Added threshold img using BINARY and OTSU *

threshold_img with THRESH_BINARY + THRESH_OTSU

1

There are 1 answers

3
Andrzej Pronobis On

I think what happens in your case is that it is very difficult to find a set of parameters that would create both horizontal and vertical lines at the same time without some lines "stealing" votes from some other lines. You could do a quick trick here and enforce detection of vertical lines only, while focus on your dominant horizontal lines later:

# Vertical lines
lines = cv2.HoughLinesP(
    threshhold_img, 1, np.pi, threshold=100, minLineLength=100, maxLineGap=1)

# Horizontal lines
lines2 = cv2.HoughLinesP(
    threshhold_img, 1, np.pi / 2, threshold=500, minLineLength=500, maxLineGap=1)

which gives me:

enter image description here