Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python cv2 HoughLines grid line detection

I have a simple grid in an image, I am trying to determine the grid size, e.g. 6x6, 12x12, etc. Using Python and cv2.

enter image description here

I am testing it with the above 3x3 grid, I was planning to determine the grid size by counting how many vertical / horizontal lines there are by detecting them in the image:

import cv2
import numpy as np

im = cv2.imread('photo2.JPG')
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

imgSplit = cv2.split(im)
flag,b = cv2.threshold(imgSplit[2],0,255,cv2.THRESH_OTSU) 

element = cv2.getStructuringElement(cv2.MORPH_CROSS,(1,1))
cv2.erode(b,element)

edges = cv2.Canny(b,150,200,3,5)

while(True):

    img = im.copy()

    lines = cv2.HoughLinesP(edges,1,np.pi/2,2, minLineLength = 620, maxLineGap = 100)[0]

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

    cv2.imshow('houghlines',img)

    if k == 27:
        break

cv2.destroyAllWindows()

My code detects the lines, as can be seen below, however there are multiple lines detected for each line in my image:

enter image description here

(there are two 1px green lines drawn for every line in the image)

I cannot simply divide the number of lines by two because (depending on the grid size) sometimes just the one line will be drawn.

How can I more accurately detect and draw a single line for every line detected in the original image?

I have tweaked threshold settings, reducing the image to black and white, yet I still get multiple lines. I assume this is because of the canny edge detection?

like image 307
StuR Avatar asked Sep 27 '13 15:09

StuR


People also ask

What is cv2 HoughLines?

Everything explained above is encapsulated in the OpenCV function, cv2. HoughLines(). It simply returns an array of (r, 0) values. r is measured in pixels and 0 is measured in radians.

What does HoughLines return?

HoughLines(). It simply returns an array of ( (\rho, \theta) values. \rho is measured in pixels and \theta is measured in radians. First parameter, Input image should be a binary image, so apply threshold or use canny edge detection before applying hough transform.

What's the difference between HoughLines and HoughLinesP?

First of all, let's detect some lines, which is done with the HoughLines and HoughLinesP functions. The only difference between the two functions is that one uses the standard Hough transform, and the second uses the probabilistic Hough transform (hence P in the name).


1 Answers

I ended up iterating through the lines and removing lines that were within 10px of one another:

lines = cv2.HoughLinesP(edges,1,np.pi/180,275, minLineLength = 600, maxLineGap = 100)[0].tolist()

for x1,y1,x2,y2 in lines:
    for index, (x3,y3,x4,y4) in enumerate(lines):

        if y1==y2 and y3==y4: # Horizontal Lines
            diff = abs(y1-y3)
        elif x1==x2 and x3==x4: # Vertical Lines
            diff = abs(x1-x3)
        else:
            diff = 0

        if diff < 10 and diff is not 0:
            del lines[index]

gridsize = (len(lines) - 2) / 2
like image 162
StuR Avatar answered Sep 29 '22 20:09

StuR