opencv求两条直线的交点

求解直线 

给出两组坐标点[x1,y1][x2,y2]确定直线Line1
Line1的方程表示为:

                                                          

分别带入两组坐标点,由于三个参数可以同比例放大缩小。所以可以用下面这一组参数来表示:

由于没有除法可以不考虑斜率为0的情况。这就是为什么不用斜率来表达方程的原因。

两直线交点

 OpenCV中有非常好用的矩阵Mat数据类型。

所以[x, y]的坐标可以用矩阵表示:

c++代码

Mat ab_matrix = (Mat_<float>(2, 2) << a1,b1,a2,b2);//两条直线的系数矩阵2*2
Mat C_matrix = (Mat_<float>(2, 1) << -c1,-c2);//两条直线的C参数矩阵2*1
Mat xy_matrix = (Mat_<float>(2, 1));//两条直线的交点坐标矩阵2*1
xy_matrix = ab_matrix.inv()*C_matrix;

原文:https://blog.csdn.net/csuyhb/article/details/81325670
//****************************************************************************************
//  求二条直线的交点的公式
//  有如下方程    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;
}


原文:https://blog.csdn.net/ycj9090900/article/details/53668753 

 Line1、Line2和交点如图:

代码求出来预期的(1,1)交点。

cv::Point 交点(cv::Point 点1, cv::Point 点2, cv::Point 点3, cv::Point 点4) {
	//计算点1,2形成直线与点3,4形成直线交点
	//如果平行或有无穷个交点就取点2和3的中间点
	int x, y;
	int X1 = 点1.x - 点2.x, Y1 = 点1.y - 点2.y, X2 = 点3.x - 点4.x, Y2 = 点3.y - 点4.y;
	//(点1.x-x)/(点1.y-y)=X1/Y1
	//(点1.x-x)Y1=X1(点1.y-y)
	//X1*y=(Y1*x+X1*点1.y-Y1*点1.x)
	//X2*y=(Y2*x+X2*点3.y-Y2*点3.x)
	if (X1*Y2 == X2*Y1)return cv::Point((点2.x + 点3.x) / 2, (点2.y + 点3.y) / 2);
 
	int A = X1*点1.y - Y1*点1.x, B = X2*点3.y - Y2*点3.x;
	//X1*y=(Y1*x+A)
	//X2*y=(Y2*x+B)
	y = (A*Y2 - B*Y1) / (X1*Y2 - X2*Y1);
	x = (B*X1 - A*X2) / (Y1*X2 - Y2*X1);
	return cv::Point(x, y);
}
int  main() {
	cv::Mat 画布(500, 500, CV_8UC3);
	画布 = cv::Scalar(255,255,255);
	cv::Point 点1(200, 100), 点2(100, 50), 点3(400, 50), 点4(100, 380);
 
	cv::circle(画布, 点1, 5, cv::Scalar(255, 0, 0), -1);
	cv::circle(画布, 点2, 5, cv::Scalar(255, 0, 0), -1);
	cv::circle(画布, 点3, 5, cv::Scalar(255, 0, 0), -1);
	cv::circle(画布, 点4, 5, cv::Scalar(255, 0, 0), -1);
	line(画布, 点2 - 点1, 3*(点2 + 点1), Scalar(111, 111, 255));
	line(画布, 点3+2*(点4 - 点3), 点3 -3 * (点4 - 点3), Scalar(111, 111, 255));
 
	cv::Point 结果 = 交点(点1, 点2, 点3, 点4);
	cv::circle(画布, 结果, 5, cv::Scalar(0, 255, 0), -1);
	std::cout << "最终坐标为" << 结果;
	cv::imshow("计算交点", 画布);
	cv::waitKey(-1);
	return 0;
}

原文:https://blog.csdn.net/zmdsjtu/article/details/78269820 
//定义Point2f结构体  
struct Point2f
{
	float x;
	float y;
};

// 定义直线参数结构体  
struct LinePara
{
	float k;
	float b;

};

// 获取直线参数  
void getLinePara(float& x1, float& y1, float& x2, float& y2, LinePara & LP)
{
	double m = 0;
	// 计算分子  
	m = x2 - x1;
	if (0 == m)
	{
		LP.k = 10000.0;
		LP.b = y1 - LP.k * x1;
	}
	else
	{
		LP.k = (y2 - y1) / (x2 - x1);
		LP.b = y1 - LP.k * x1;
	}
}

// 获取交点  
bool getCross(float & x1, float &y1, float & x2, float & y2, float & x3, float &y3, float & x4, float & y4,  Point2f & pt){
	LinePara para1, para2;
	getLinePara(x1, y1, x2, y2, para1);
	getLinePara(x3, y3, x4, y4, para2);

	// 判断是否平行  
	if (abs(para1.k - para2.k) > 0.5)
	{
		pt.x = (para2.b - para1.b) / (para1.k - para2.k);
		pt.y = para1.k * pt.x + para1.b;

		return true;

	}
	else
	{
		return false;
	}
}

void main()
{
	Point2f pt1, pt2, pt3, pt4, pt;
	pt1.x = 1.0;
	pt1.y = 1.0;

	pt2.x = 2.0;
	pt2.y = 2.0;

	pt3.x = 0.0;
	pt3.y = 2.0;

	pt4.x = 2.0;
	pt4.y = 0.0;

	getCross(pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y, pt4.x, pt4.y, pt);

	cout << pt.x << " , " << pt.y << endl;
}


原文:https://blog.csdn.net/sinat_31425585/article/details/74947640 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值