I have an image and it has some shapes in it. I detected lines with using hough lines. How can I detect which lines are parallel?
Two lines y = k1 * x + b1, y = k2 * x + b2 are parallel, if k1 = k2. So you need to calculate coefficient k for each detected line. In order to uniquely identify the equation of a line you need to know the coordinates of two points that belong to line.
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.
Use the HoughLinesP() Function of OpenCV to Detect Lines in an Image in Python. The HoughLinesP() function uses probabilistic Hough line transform to detect lines. We have to read the given image using the imread() function, convert it into grayscale, and then find its edges using Canny() .
Everything explained above is encapsulated in the OpenCV function, cv2.HoughLines(). It simply returns an array of. values. is measured in pixels and is measured in radians. First parameter, Input image should be a binary image, so apply threshold or use canny edge detection before finding applying hough transform.
As John proposed, the easiest way is to detect similar angles. OpenCVs HoughLines function represents a line by means of its distance to the origin and an angle.
So what you could basically do is to cluster the different angles with a hierarchical clustering algorithm:
from scipy.spatial.distance import pdist
from scipy.cluster.hierarchy import ward, fcluster
img = cv2.imread('images/img01.bmp')
img_canny = cv2.Canny(img, 50, 200, 3)
lines = cv2.HoughLines(img_canny, 1, 5* np.pi / 180, 150)
def find_parallel_lines(lines):
lines_ = lines[:, 0, :]
angle = lines_[:, 1]
# Perform hierarchical clustering
angle_ = angle[..., np.newaxis]
y = pdist(angle_)
Z = ward(y)
cluster = fcluster(Z, 0.5, criterion='distance')
parallel_lines = []
for i in range(cluster.min(), cluster.max() + 1):
temp = lines[np.where(cluster == i)]
parallel_lines.append(temp.copy())
return parallel_lines
Equation of a line in Cartesian coordinates:
y = k * x + b
Two lines y = k1 * x + b1, y = k2 * x + b2 are parallel, if k1 = k2.
So you need to calculate coefficient k for each detected line.
In order to uniquely identify the equation of a line you need to know the coordinates of two points that belong to line.
After having found lines with HoughLines (С++):
vector<Vec2f> lines;
HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 );
you have the vector lines, which stores the parameters (r,theta) of the detected lines in polar coordinates. You need to transfer them in Cartesian coordinates:
Here example in C++:
for( size_t i = 0; i < lines.size(); i++ )
{
float rho = lines[i][0], theta = lines[i][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 1000*(-b)); //the first point
pt1.y = cvRound(y0 + 1000*(a)); //the first point
pt2.x = cvRound(x0 - 1000*(-b)); //the second point
pt2.y = cvRound(y0 - 1000*(a)); //the second point
}
After having got these two points of a line you can calculate its equation.
HoughLines returns its results in Polar coordinates. So just check the 2nd value for the angle. No need to convert to x,y
def findparallel(lines):
lines1 = []
for i in range(len(lines)):
for j in range(len(lines)):
if (i == j):continue
if (abs(lines[i][1] - lines[j][1]) == 0):
#You've found a parallel line!
lines1.append((i,j))
return lines1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With