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?
-
If this is done in python, as stated in the tags, you can use the scipy version of houghlines, which provides the houghspace output image: See here](scikit-image.org/docs/dev/auto_examples/…). You can then perhaps flip the independent axis (theta or 'X') and the dependent axis (rho or 'Y') such that theta is now the dependent axis. After thresholding this Hough space image (to get the most intense spots of (rho, theta) that correspond to the most likely lines), you can fit a horizontal line to the data: theta = constant (y=mx+b with no slope).chase– chase2016-06-10 17:36:30 +00:00Commented Jun 10, 2016 at 17:36
3 Answers
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
1 Comment
if (abs(lines[i][0][1] - lines[j][0][1]) == 0): 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
