2011-09-16 12 views
12

OpenCVで2行の交差を計算するためのヘルパ関数を探していました。 APIドキュメントを検索しましたが、有用なリソースが見つかりませんでした。OpenCV 2d行交差ヘルパー関数

OpenCVの線分/線分の交差/距離計算に基本的な幾何学的ヘルパー関数はありますか?

答えて

38

ありラインの交点を計算するためにOpenCVのAPIには関数ではありませんが、距離は次のとおりです。

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

あなたがラインの交点を計算するコードの一部を必要とする場合は、ここにある:

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

説明のためだけです。あなたの例の中の線は、2点で定義されているか、または点と方向ベクトルとして定義されていますか? – tisch

+0

2点で定義されています。関数内で計算された 'd1'と' d2'は方向ベクトルです。 –

+0

ありがとうヘルパー機能! – tisch

1

ここにEmguCV(C#)の実装があります。 Pythonで

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

私の実装(numpyのアレイを使用して) LINE1 = [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&x2、y2は(0.0,1.0)&(2.0,1.0)のように浮動小数点にする必要があります – afiah

+0

このコードは垂直線がある場合は機能しません。 ei [0]) –

2

は、あなたの人生が容易になり:第三の座標場合は0ラインは平行であり、溶液はR²ではなく、P^2に存在しない、その後POINあること

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

注tは2Dの方向を意味します。

+0

'point'の形は何ですか?この関数から何も返されません。 – Geoff

1

ラインの交点を求めるアルゴリズムは、ポスト私のOpenCVのC++実装で、次のHow do you detect where two line segments intersect?

に非常によく記載されています。上記の表記と同じ記法を使用します。

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