Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Choosing Lines From Hough Lines

I'm using Hough Lines to do corner detection for this image. i plan to find the intersection of the lines as the corner. This is the image. enter image description here

Unfortunately, Hough return lots of lines for each line I expect enter image description here

How do I tune the Hough Lines so there is only four lines each corresponds to actual line on the image?

like image 380
IllSc Avatar asked Aug 14 '14 08:08

IllSc


People also ask

How can lines be detected using Hough transform?

If two edge points lay on the same line, their corresponding cosine curves will intersect each other on a specific (ρ, θ) pair. Thus, the Hough Transform algorithm detects lines by finding the (ρ, θ) pairs that have a number of intersections larger than a certain threshold.

What does Hough lines 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.

How to find straight lines in an image using Hough Lines?

Therefore, probably the most common solution is to firstly grayscale the image and then to detect edges. Such mask of edges can be then fetched to the Hough Lines method which should output a set of straight lines found on an image. As we learned from quite early school classes, the straight line can be represented by two parameters.

How does the Hough line transform work?

The Hough Line Transform is a transform used to detect straight lines. To apply the Transform, first an edge detection pre-processing is desirable. How does it work? As you know, a line in the image space can be expressed with two variables. For example: In the Cartesian coordinate system: Parameters: (m,b).

How to use houghlines in OpenCV?

Hough transform is fairly simple) For the non-probabilistic hough transform, OpenCv will return the lines in order of their confidence, with the strongest line first. So simply take the first four lines that differ strongly in either rho or theta. so, add the first line found by HoughLines into a new List: strong_lines

What is houghlinesp and how to use it?

It’s named HoughLinesP. P suffix stands for probabilistic here. It has more efficient implementation and the function outputs extremes of detected lines which can be very useful. Below, there is an example of the same image with the straight lines found using HoughLinesP.


3 Answers

I implemented the approach described by HugoRune and though I would share my code as an example of how I implemented this. I used a tolerance of 5 degrees and 10 pixels.

strong_lines = np.zeros([4,1,2])

minLineLength = 2
maxLineGap = 10
lines = cv2.HoughLines(edged,1,np.pi/180,10, minLineLength, maxLineGap)

n2 = 0
for n1 in range(0,len(lines)):
    for rho,theta in lines[n1]:
        if n1 == 0:
            strong_lines[n2] = lines[n1]
            n2 = n2 + 1
        else:
            if rho < 0:
               rho*=-1
               theta-=np.pi
            closeness_rho = np.isclose(rho,strong_lines[0:n2,0,0],atol = 10)
            closeness_theta = np.isclose(theta,strong_lines[0:n2,0,1],atol = np.pi/36)
            closeness = np.all([closeness_rho,closeness_theta],axis=0)
            if not any(closeness) and n2 < 4:
                strong_lines[n2] = lines[n1]
                n2 = n2 + 1

EDIT: The code was updated to reflect the comment regarding a negative rho value

like image 55
Onamission21 Avatar answered Oct 17 '22 16:10

Onamission21


OpenCVs hough transform really could use some better Non-Maximum Suppression. Without that, you get this phenomenon of duplicate lines. Unfortunately I know of no easy way to tune that, besides reimplementing your own hough transform. (Which is a valid option. Hough transform is fairly simple)

Fortunately it is easy to fix in post-processing:

For the non-probabilistic hough transform, OpenCv will return the lines in order of their confidence, with the strongest line first. So simply take the first four lines that differ strongly in either rho or theta.

  • so, add the first line found by HoughLines into a new List: strong_lines
  • for each line found by HoughLines:
    • test whether its rho and theta are close to any strong_line (e.g. rho is within 50 pixels and theta is within 10° of the other line)
    • if not, put it into the list of strong_lines
    • if you have found 4 strong_lines, break
like image 13
HugoRune Avatar answered Oct 17 '22 14:10

HugoRune


Collect the intersection of all line

for (int i = 0; i < lines.size(); i++)
{
    for (int j = i + 1; j < lines.size(); j++)
    {       
        cv::Point2f pt = computeIntersectionOfTwoLine(lines[i], lines[j]);
        if (pt.x >= 0 && pt.y >= 0 && pt.x < image.cols && pt.y < image.rows)
        {
            corners.push_back(pt);
        }
    }
}

You can google the algorithm to find the intersection of two lines. Once you collect all the intersection points you can easily determine the min max which will give you top-left and bottom right points. From these two points you can easily get the rectangle.

Here Sorting 2d point array to find out four corners & http://opencv-code.com/tutorials/automatic-perspective-correction-for-quadrilateral-objects/ Refer these two links.

like image 2
Rahul galgali Avatar answered Oct 17 '22 16:10

Rahul galgali