2011-09-16 37 views
12

Tôi đang tìm một hàm trợ giúp để tính toán giao điểm của hai dòng trong OpenCV. Tôi đã tìm kiếm Tài liệu API nhưng không thể tìm thấy tài nguyên hữu ích.Chức năng trợ giúp giao nhau đường dây OpenCV 2d

Có các hàm trợ giúp hình học cơ bản cho các phép tính giao cắt/khoảng cách trên các đoạn đường thẳng/đường trong OpenCV không?

Trả lời

38

Không có chức năng trong OpenCV API để tính toán dòng giao nhau, nhưng khoảng cách là:

cv::Point2f start, end; 
double length = cv::norm(end - start); 

Nếu bạn cần một đoạn mã để tính toán nút giao thông đường sau đó ở đây là:

// Finds the intersection of two lines, or returns false. 
// The lines are defined by (o1, p1) and (o2, p2). 
bool intersection(Point2f o1, Point2f p1, Point2f o2, Point2f p2, 
         Point2f &r) 
{ 
    Point2f x = o2 - o1; 
    Point2f d1 = p1 - o1; 
    Point2f d2 = p2 - o2; 

    float cross = d1.x*d2.y - d1.y*d2.x; 
    if (abs(cross) < /*EPS*/1e-8) 
     return false; 

    double t1 = (x.x * d2.y - x.y * d2.x)/cross; 
    r = o1 + d1 * t1; 
    return true; 
} 
+0

Chỉ để làm rõ. Có phải các dòng trong ví dụ của bạn được xác định bởi hai điểm, hoặc là một điểm và một vector hướng? – tisch

+0

Chúng được xác định bởi hai điểm. 'd1' và' d2' được tính bên trong hàm là các vectơ hướng. –

+0

Cảm ơn chức năng trợ giúp! – tisch

1

Đây là thực hiện của tôi cho EmguCV (C#).

static PointF GetIntersection(LineSegment2D line1, LineSegment2D line2) 
{ 

    double a1 = (line1.P1.Y - line1.P2.Y)/(double)(line1.P1.X - line1.P2.X); 
    double b1 = line1.P1.Y - a1 * line1.P1.X; 

    double a2 = (line2.P1.Y - line2.P2.Y)/(double)(line2.P1.X - line2.P2.X); 
    double b2 = line2.P1.Y - a2 * line2.P1.X; 

    if (Math.Abs(a1 - a2) < double.Epsilon) 
     throw new InvalidOperationException(); 

    double x = (b2 - b1)/(a1 - a2); 
    double y = a1 * x + b1; 
    return new PointF((float)x, (float)y); 
} 
0

thực hiện của tôi trong Python (sử dụng mảng NumPy) với line1 = [[x1, y1], [x2, y2]] & dòng2 = [[x1, y1], [x2, y2]]

def getIntersection(line1, line2): 
    s1 = numpy.array(line1[0]) 
    e1 = numpy.array(line1[1]) 

    s2 = numpy.array(line2[0]) 
    e2 = numpy.array(line2[1]) 

    a1 = (s1[1] - e1[1])/(s1[0] - e1[0]) 
    b1 = s1[1] - (a1 * s1[0]) 

    a2 = (s2[1] - e2[1])/(s2[0] - e2[0]) 
    b2 = s2[1] - (a2 * s2[0]) 

    if abs(a1 - a2) < sys.float_info.epsilon: 
     return False 

    x = (b2 - b1)/(a1 - a2) 
    y = a1 * x + b1 
    return (x, y) 
+0

x1, y1 & x2, y2 phải nổi như (0.0, 1.0) & (2.0, 1.0) – afiah

+0

Mã này không hoạt động với sự hiện diện của một đường thẳng đứng, vì các đơn vị bởi (si [0] - ei [0]) –

2

Sử dụng tọa độ đồng nhất làm cho cuộc sống của bạn dễ dàng hơn:

cv::Mat intersectionPoint(const cv::Mat& line1, const cv::Mat& line2) 
{ 
    // Assume we receive lines as l=(a,b,c)^T 
    assert(line1.rows == 3 && line1.cols = 1 
      && line2.rows == 3 && line2.cols == 1); 

    // Point is p=(x,y,w)^T 
    cv::Mat point = line1.cross(line2); 

    // Normalize so it is p'=(x',y',1)^T 
    if(point.at<double>(2,0) != 0) 
    point = point * (1.0/point.at<double>(2,0)); 
} 

Lưu ý rằng nếu thứ ba phối hợp là 0 các đường song song và không có giải pháp trong R² nhưng trong P^2, và sau đó là poin t có nghĩa là một hướng trong 2D.

+0

Hình dạng của 'điểm' là gì? Không có gì được trả về từ hàm này. – Geoff

1

Một thuật toán cho việc tìm kiếm ngã tư đường được mô tả rất tốt trong bài How do you detect where two line segments intersect?

Sau đây là OpenCV c của tôi ++ thực hiện. Nó sử dụng cùng một ký hiệu như ở trên bài đăng

bool getIntersectionPoint(Point a1, Point a2, Point b1, Point b2, Point & intPnt){ 
    Point p = a1; 
    Point q = b1; 
    Point r(a2-a1); 
    Point s(b2-b1); 

    if(cross(r,s) == 0) {return false;} 

    double t = cross(q-p,s)/cross(r,s); 

    intPnt = p + t*r; 
    return true; 
} 

double cross(Point v1,Point v2){ 
    return v1.x*v2.y - v1.y*v2.x; 
} 
Các vấn đề liên quan