求取二直线交点(基于OpenCv)
理论补充:
两直线是否有交点(或线段齐延长线是否相交)是一个Line-line intersection(Wikipedia)问题
在一个2维平面中有两直线(点
到点
、
(点
到点
,这两条直线的交点
用行列式表示如下:
行列式可变形写作:
该交点是由4个点、两两一组确定的线段所在位置的直线的交点
根据贝塞尔参数可以将两直线定义为:
其中和
均是实数、且
和
分别为:
当且
时、存在交点P。那么在满足交点
存在的情况下,交点可以表示为:
当两直线平行或者重合的时候:t、u对应的表达式的分母为0:
理解了两条直线的叉乘之后用opencv学习了一个能求取两条直线交点的代码,而且发现很多人都遇到求直线交点的问题,然后就把我学习到的代码贴出来,希望能对你有所帮助
代码如下:
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
//****************************************************************************************
// 求二条直线的交点的公式
// 有如下方程 a1*x+b1*y=c1
// a2*x+b2*y=c2
// x= | c1 b1| / | a1 b1 | y= | a1 c1| / | a1 b1 |
// | c2 b2| / | a2 b2 | | a2 c2| / | a2 b2 |
//
// a1= (L1.pEnd.y-L1.pStart.y)
// b1= (L1.pEnd.x-L1.pStart.x)
// c1= L1.pStart.x*(L1.pEnd.y-L1.pStart.y)-(L1.pEnd.x-L1.pStart.x)*L1.pStart.y
// a2= (L2.pEnd.y-L2.pStart.y)
// b2= (L2.pEnd.x-L2.pStart.x)
// c2= L2.pStart.x*(L2.pEnd.y-L2.pStart.y)-(L2.pEnd.x-L2.pStart.x)*L2.pStart.y
//定义两个结构体方便理解
struct PT
{
int x;
int y;
};
struct LINE
{
PT pStart;
PT pEnd;
};
Point CrossPoint(const LINE *line1, const LINE *line2)
{
// if(!SegmentIntersect(line1->pStart, line1->pEnd, line2->pStart, line2->pEnd))
// {// segments not cross
// return 0;
// }
Point pt;
// line1's cpmponent
double X1 = line1->pEnd.x - line1->pStart.x;//b1
double Y1 = line1->pEnd.y - line1->pStart.y;//a1
// line2's cpmponent
double X2 = line2->pEnd.x - line2->pStart.x;//b2
double Y2 = line2->pEnd.y - line2->pStart.y;//a2
// distance of 1,2
double X21 = line2->pStart.x - line1->pStart.x;
double Y21 = line2->pStart.y - line1->pStart.y;
// determinant
double D = Y1*X2 - Y2*X1;// a1b2-a2b1
//
if (D == 0) return 0;
// cross point
pt.x = (X1*X2*Y21 + Y1*X2*line1->pStart.x - Y2*X1*line2->pStart.x) / D;
// on screen y is down increased !
pt.y = -(Y1*Y2*X21 + X1*Y2*line1->pStart.y - X2*Y1*line2->pStart.y) / D;
// segments intersect.
if ((abs(pt.x - line1->pStart.x - X1 / 2) <= abs(X1 / 2)) &&
(abs(pt.y - line1->pStart.y - Y1 / 2) <= abs(Y1 / 2)) &&
(abs(pt.x - line2->pStart.x - X2 / 2) <= abs(X2 / 2)) &&
(abs(pt.y - line2->pStart.y - Y2 / 2) <= abs(Y2 / 2)))
{
return pt;
}
return 0;
}
int main()
{
LINE line1, line2;
line1.pStart.x = 0;
line1.pStart.y = 0;
line1.pEnd.x = 2;
line1.pEnd.y = 2;
line2.pStart.x = 0;
line2.pStart.y = 2;
line2.pEnd.x = 2;
line2.pEnd.y = 0;
Point cross = CrossPoint(&line1, &line2);
cout << "CrossPoint: " << "(" << cross.x << "," << cross.y << ")" << endl;
system("pause");
return 0;
}
Line1、Line2和交点如图:
代码运行结果:
求出来预期的(1,1)交点。
鄙人刚入门Opencv才疏学浅,尚有不足还望不惜赐教。
版权声明:本文为ycj9090900原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。