- Line detection in python with OpenCV?
- Hough transform?
- Detect lines from an image using Hough transform
- Accumulator
- Hough Transform in OpenCV
- Example
- Python opencv line detection
- Theory
- Hough Line Transform
- How does it work?
- Standard and Probabilistic Hough Line Transform
- What does this program do?
- Code
- Line detection in python with OpenCV | Houghline method
- OpenCV Line Detection
- Use the HoughLines() Function of OpenCV to Detect Lines in an Image in Python
Line detection in python with OpenCV?
In this post, we are going to learn, how to detect lines in an image, with the help of a technique called Hough transform.
Hough transform?
Hough transform is a feature extraction method to detect any simple shape, if you can represent that shape in mathematical form. It somehow manage to detect the shape even if it is broken or distorted a little bit. We will see how it works for a line.
A “simple” shape is one that can be represented by only a few parameters. For example, a line can be represented by two parameters only (slope, intercept) and a circle has three parameters – the coordinates of the center and the radius (x,y, r).
Detect lines from an image using Hough transform
A line can be represented by an equation- or in parametric form it can be representated as, as where (ρ) is the perpendicular distance from origin to the line, and ϴ is the angle formed by this perpendicular line and horizontal axis measured in counter-clockwise (This representation is used in OpenCV). Check below image
So if line is passing below the origin, it will have a positive rho and angle less than 180. If it is going above the origin, instead of taking angle greater than 180, angle is taken less than 180, and rho is taken negative. Any vertical line will have 0 degree and horizontal lines will have 90 degree.
Accumulator
Any line can be representated in these two terms (ρ,ϴ). So first it creates a 2D array or accumulator (to hold values of two parameters) and it is set to 0 initially. Where rows denote the ρ and columns denote the ϴ. Size of array depends on the accuracy we need, for example, if we need accuracy of angles to be 1 degree, you need 180 columns and ρ, is the maximum distance possible is the diagonal length of the image and ρ is the maximum distance possible is the diagonal length of the image. So taking one pixel accuracy and number of rows can be diagonal length of the image.
Consider we have an image of 100*100 with a horizontal line at the middle. Take the first point of the line, and we know its (x,y) values. Now in the equation, pu the values ϴ=0,1,2,3…180 and check the ρ value you get. For every (ρ,ϴ) pair, increment value by one is our accumulator in its corresponding (ρ,ϴ) cells. So now in accumulator, the cell (50,90) = 1 along with some other cells. Now take the second spot on the line. Repeat the same procedure as we did for first spot. Increment the values in the cells corresponding to (ρ,ϴ) you get. This time, the cell (50,90)=2. So we are actually voting the (ρ,ϴ) values. We continue this process for every point on the line. At each spot, the cell (50,90) will be incremented or voted up, while other cells may not be voted up. This way, at the end, the cell(50,90) will have maximum votes. So if you search the accumulator for maximum votes, you get the value (50,90) which says, there is a line in this image at distance 50 from origin and at angle 90 degrees. This is how hough transform for lines works.
Hough Transform in OpenCV
Everything explained above is encapsulated in the OpenCV function, cv2.HoughLines(). It simply returns an array of (ρ,ϴ) values where ρ is measured in pixels and ϴ is measured in radians.
Below is a program of line detection using openCV and hough line transform.
Below is actual image of a parking lot, and we are going to do line detection on this image using hough line transform and OpenCV library.
Example
import cv2 import numpy as np img = cv2.imread("parkingLot1.jpg") gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 75, 150) lines = cv2.HoughLinesP(edges, 1, np.pi/180, 30, maxLineGap=250) for line in lines: x1, y1, x2, y2 = line[0] cv2.line(img, (x1, y1), (x2, y2), (0, 0, 128), 1) cv2.imshow("linesEdges", edges) cv2.imshow("linesDetected", img) cv2.waitKey(0) cv2.destroyAllWindows()
Python opencv line detection
In this tutorial you will learn how to:
Theory
Hough Line Transform
- 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)\).
- In the Polar coordinate system: Parameters: \((r,\theta)\)
For Hough Transforms, we will express lines in the Polar system. Hence, a line equation can be written as:
Arranging the terms: \(r = x \cos \theta + y \sin \theta\)
- In general for each point \((x_, y_)\), we can define the family of lines that goes through that point as: \[r_ = x_ \cdot \cos \theta + y_ \cdot \sin \theta\] Meaning that each pair \((r_,\theta)\) represents each line that passes by \((x_, y_)\).
- If for a given \((x_, y_)\) we plot the family of lines that goes through it, we get a sinusoid. For instance, for \(x_ = 8\) and \(y_ = 6\) we get the following plot (in a plane \(\theta\) — \(r\)):
Standard and Probabilistic Hough Line Transform
OpenCV implements two kind of Hough Line Transforms:
a. The Standard Hough Transform
- It consists in pretty much what we just explained in the previous section. It gives you as result a vector of couples \((\theta, r_)\)
- In OpenCV it is implemented with the function HoughLines()
b. The Probabilistic Hough Line Transform
- A more efficient implementation of the Hough Line Transform. It gives as output the extremes of the detected lines \((x_, y_, x_, y_)\)
- In OpenCV it is implemented with the function HoughLinesP()
What does this program do?
- Loads an image
- Applies a Standard Hough Line Transform and a Probabilistic Line Transform.
- Display the original image and the detected line in three windows.
Code
The sample code that we will explain can be downloaded from here. A slightly fancier version (which shows both Hough standard and probabilistic with trackbars for changing the threshold values) can be found here.
Line detection in python with OpenCV | Houghline method
The Hough Transform is a method that is used in image processing to detect any shape, if that shape can be represented in mathematical form. It can detect the shape even if it is broken or distorted a little bit.
We will see how Hough transform works for line detection using the HoughLine transform method. To apply the Houghline method, first an edge detection of the specific image is desirable. For the edge detection technique go through the article Edge detectionBasics of Houghline Method
A line can be represented as y = mx + c or in parametric form, as r = xcosθ + ysinθ where r is the perpendicular distance from origin to the line, and θ is the angle formed by this perpendicular line and horizontal axis measured in counter-clockwise ( That direction varies on how you represent the coordinate system. This representation is used in OpenCV).
So Any line can be represented in these two terms, (r, θ).
Working of Houghline method:- First it creates a 2D array or accumulator (to hold values of two parameters) and it is set to zero initially.
- Let rows denote the r and columns denote the (θ)theta.
- Size of array depends on the accuracy you need. Suppose you want the accuracy of angles to be 1 degree, you need 180 columns(Maximum degree for a straight line is 180).
- For r, the maximum distance possible is the diagonal length of the image. So taking one pixel accuracy, number of rows can be diagonal length of the image.
Example:
Consider a 100×100 image with a horizontal line at the middle. Take the first point of the line. You know its (x,y) values. Now in the line equation, put the values θ(theta) = 0,1,2,….,180 and check the r you get. For every (r, 0) pair, you increment value by one in the accumulator in its corresponding (r,0) cells. So now in accumulator, the cell (50,90) = 1 along with some other cells.
Now take the second point on the line. Do the same as above. Increment the values in the cells corresponding to (r,0) you got. This time, the cell (50,90) = 2. We are actually voting the (r,0) values. You continue this process for every point on the line. At each point, the cell (50,90) will be incremented or voted up, while other cells may or may not be voted up. This way, at the end, the cell (50,90) will have maximum votes. So if you search the accumulator for maximum votes, you get the value (50,90) which says, there is a line in this image at distance 50 from origin and at angle 90 degrees.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.
OpenCV Line Detection
- Use the HoughLines() Function of OpenCV to Detect Lines in an Image in Python
- Use the HoughLinesP() Function of OpenCV to Detect Lines in an Image in Python
This tutorial will discuss detecting lines in an image using the HoughLines() and HoughLinesP() function of OpenCV in Python.
Use the HoughLines() Function of OpenCV to Detect Lines in an Image in Python
The HoughLines() function of OpenCV is used to detect lines present in an image using the standard Hough line transform.
To detect the lines present in an image, we have to read the image using the imread() function and convert it into grayscale if it’s not in grayscale already.
After that, we have to find the edges of the given image using the Canny() function of OpenCV. The first argument of the Canny() function is the given image.
The second and third arguments are the first and second threshold values for the hysteresis procedure. The fourth argument is the aperture size, and the fifth is the gradient value.
The Canny() function’s output contains the edges of the given image according to the threshold. We have to pass the edges inside the HoughLines() function to detect the lines present in the image.
The first argument of the HoughLines() function is the output of the edge detector, and it should be a grayscale image. The second argument is the resolution of the parameters in pixels.
The third argument is the resolution of parameters in radians. The fourth argument is the threshold used as the minimum number of intersections inline detection.
The other arguments are default parameters. After that, we have to use a loop to draw each line one by one on the original image using the line() function of OpenCV.
After that, we can show the original image and the image with detected lines using the imshow() function of OpenCV.
For example, let’s detect the lines present in a sudoku image.
import cv2 as cv import numpy as np import math src_img = cv.imread('test.png') cv.imshow('Original Image',src_img) dst_img = cv.Canny(src_img, 50, 200, None, 3) lines = cv.HoughLines(dst_img, 1, np.pi / 180, 150, None, 0, 0) for i in range(0, len(lines)): rho_l = lines[i][0][0] theta_l = lines[i][0][1] a_l = math.cos(theta_l) b_l = math.sin(theta_l) x0_l = a_l * rho_l y0_l = b_l * rho_l pt1_l = (int(x0_l + 1000*(-b_l)), int(y0_l + 1000*(a_l))) pt2_l = (int(x0_l - 1000*(-b_l)), int(y0_l - 1000*(a_l))) cv.line(src_img, pt1_l, pt2_l, (0,0,255), 3, cv.LINE_AA) cv.imshow("Image with lines", src_img) cv.waitKey(0)