2011-09-16 29 views
12

Estaba buscando una función auxiliar para calcular la intersección de dos líneas en OpenCV. He buscado la documentación de la API, pero no he podido encontrar un recurso útil.OpenCV 2d línea intersección ayudante función

¿Hay funciones auxiliares geométricas básicas para los cálculos de intersección/distancia en líneas/segmentos de línea en OpenCV?

Respuesta

38

No hay función en la API de OpenCV para calcular líneas de intersección, pero la distancia es:

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

Si necesita una pieza de código para calcular intersecciones de las líneas a continuación, aquí está:

// 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

Solo para aclaración. ¿Las líneas en su ejemplo están definidas por dos puntos, o como un punto y un vector de dirección? – tisch

+0

Están definidos por dos puntos. 'd1' y' d2' calculados dentro de la función son vectores de dirección. –

+0

Gracias a la función de ayuda! – tisch

1

Aquí está mi implementación para 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

mi aplicación en Python (usando array numpy) con línea 1 = [[x1, y1], [x2, y2]] & line2 = [[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 y x2, y2 tiene que ser flotante como (0.0, 1.0) y (2.0, 1.0) – afiah

+0

Este código no funciona en presencia de una línea vertical, debido a las divisiones por (si [0] - ei [0]) –

2

Usando coordenadas homogéneas hace la vida más fácil:

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)); 
} 

Tenga en cuenta que si la tercera coordenada es 0 las líneas son paralelas y no hay solución en R² pero en P^2, y luego el poin t significa una dirección en 2D.

+0

¿Cuál es la forma de 'punto'? No se devuelve nada de esta función. – Geoff

1

Un algoritmo para encontrar la línea de intersección se describe muy bien en el post How do you detect where two line segments intersect?

La siguiente es mi OPENCV implementación en C++. Utiliza la misma notación que en la publicación anterior

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; 
} 
Cuestiones relacionadas