Python How to detect vertical and horizontal lines in an image with HoughLines with OpenCV?

41,573

Solution 1

You are using too small value for rho.

Try the below code:-

import numpy as np
import cv2

gray = cv2.imread('lines.jpg')
edges = cv2.Canny(gray,50,150,apertureSize = 3)
cv2.imwrite('edges-50-150.jpg',edges)
minLineLength=100
lines = cv2.HoughLinesP(image=edges,rho=1,theta=np.pi/180, threshold=100,lines=np.array([]), minLineLength=minLineLength,maxLineGap=80)

a,b,c = lines.shape
for i in range(a):
    cv2.line(gray, (lines[i][0][0], lines[i][0][1]), (lines[i][0][2], lines[i][0][3]), (0, 0, 255), 3, cv2.LINE_AA)
    cv2.imwrite('houghlines5.jpg',gray)

Note, the change in rho value, pi value and maxLineGap to reduce outliers.

Input Image Input Image

Edges Image Edges Image

Output Image Output Image

Miscellaneous - Tips for Beginners

  1. A lot of Computer Vision algorithms assume certain assumptions, well, in how the input should be. When building Proof-of-Concept, always try to view intermediate inputs you generate before applying such algorithms.

  2. For quick hack, if an algorithm accepts some parameters, use a for loop on possible values of these parameters and see how the results varies. Link to an answer on how to quickly generate these possible values.

  3. To really understand the algorithm, read on wiki or even better sources where if necessary. And then again/still do the above hack(point 2). It will further clear your understanding.

Solution 2

I would rather write this as a comment but unfortunately I can't. You should change the minLineLength and minLineGap. Or what if its just sqaures that you have to find, I would get all the lines and check the angles between them to get lines only along squares. I have worked with HoughLineP before and it is pretty much based on the above two arguments. Additionally, try using Bilateral filtering. I really helps when the sharpening using median filter doesn't help.

Bilateral Filter

Share:
41,573

Related videos on Youtube

user3601754
Author by

user3601754

Updated on July 09, 2022

Comments

  • user3601754
    user3601754 almost 2 years

    I m trying to obtain a threshold of the calibration chessboard. I cant detect directly the chessboard corners as there is some dust as i observe a micro chessboard. I try several methods and HoughLinesP seems to be the easiest approach. But the results are not good, how to improve my results?

    import numpy as np
    import cv2
    
    img = cv2.imread('lines.jpg')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray,50,150,apertureSize = 3)
    print img.shape[1]
    print img.shape
    minLineLength=100
    lines = cv2.HoughLinesP(image=edges,rho=0.02,theta=np.pi/500, threshold=10,lines=np.array([]), minLineLength=minLineLength,maxLineGap=100)
    
    a,b,c = lines.shape
    for i in range(a):
        cv2.line(img, (lines[i][0][0], lines[i][0][1]), (lines[i][0][2], lines[i][0][3]), (0, 0, 255), 3, cv2.LINE_AA)
        cv2.imwrite('houghlines5.jpg',img)
    

    As you can see on figure below, i cant obtain my chessboard, the lines are plotted in a lot of directions... (the original picture : https://s22.postimg.org/iq2b91xq9/droite_Image_00000.jpg)

    enter image description here

    • linusg
      linusg over 7 years
      Use thresholding, or try to reduce the small points (erode, dilate).
    • user3601754
      user3601754 over 7 years
      I already try but not coupled with hough lines. Perhaps it could help to obtain the lines? thanks for your hellp ;)
    • linusg
      linusg over 7 years
      I really would thresholding give another try!
    • rayryeng
      rayryeng over 7 years
      Can you upload the original image? I also agree with giving thresholding a try combined with morphological analysis. I can give this a try myself if I had the original image.
    • rayryeng
      rayryeng over 7 years
      Also, is it specifically required to use the Hough Transform? If you remove some of the noise, perform a rather large closing then find the corners (Harris for example), that should solve your problem.
    • user3601754
      user3601754 over 7 years
      Ok i do that i add it in the question ;)
    • user3601754
      user3601754 over 7 years
      I try to remove the noise with median filter but it is not sufficient or to labellize the square to isolate it. But the result is not very good i mean the reprojection error is sometimes important (RMS > 1)
    • GpG
      GpG over 7 years
      if you are not required to implement your own solution you can try with an already implemented method docs.opencv.org/2.4/doc/tutorials/calib3d/…
    • user3601754
      user3601754 over 7 years
      Yep i know ;) but the picture is too noisy it doesnt work that is why i do this solution ;)
  • lucians
    lucians almost 7 years
    how to save the image without the red lines ? I would like to have the image without all the lines at all. Thanks
  • saurabheights
    saurabheights almost 7 years
    @Link - I am not sure what you meant by image without the lines. If you just need to output the original image, just use cv2.imwrite('imagename.jpg',gray), before drawing hough lines, i.e. before running command cv2.line and use imwrite outside the loop.
  • Parikshit Chalke
    Parikshit Chalke about 5 years
    How to get contours of each box?? Means I want to detect the boxes in image with there co-ordinates.
  • saurabheights
    saurabheights about 5 years
    @ParikshitChalke There are many ways to do it, but simplest would be to use information from these edges and try fitting a chess edges(8x8 squares) over the input image. By fitting, I mean use some loss, such as SSD. Furthermore, please post a new question for different problems.