简体   繁体   中英

Python openCV detect parallel lines

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?

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM