Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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

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.

enter image description here

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top