在 OpenCV 中,cv::fitLine()
返回的直线参数是 方向向量(vx, vy
)和直线上一点(x0, y0
)。要计算两条直线的交点,可以使用 向量几何法 或 参数方程法。以下是详细步骤和代码实现:
1. 直线表示方法
2. 计算两条直线的交点
3. 代码实现
#include <opencv2/opencv.hpp> #include <iostream> cv::Point2f computeIntersection(const cv::Vec4f& line1, const cv::Vec4f& line2) { float vx1 = line1[0], vy1 = line1[1], x01 = line1[2], y01 = line1[3]; float vx2 = line2[0], vy2 = line2[1], x02 = line2[2], y02 = line2[3]; // 计算行列式 float D = vx2 * vy1 - vx1 * vy2; if (std::abs(D) < 1e-6) { // 平行或重合 return cv::Point2f(-1, -1); // 无交点 } // 计算 t1 和 t2 float dx = x02 - x01, dy = y02 - y01; float t1 = (dx * (-vy2) - dy * (-vx2)) / D; float t2 = (vx1 * dy - vy1 * dx) / D; // 计算交点 float x = x01 + t1 * vx1; float y = y01 + t1 * vy1; return cv::Point2f(x, y); } int main() { // 示例:两条直线的参数(方向向量 + 直线上一点) cv::Vec4f line1(0.707, 0.707, 100, 100); // 方向 (1,1),经过 (100,100) cv::Vec4f line2(-0.707, 0.707, 200, 100); // 方向 (-1,1),经过 (200,100) cv::Point2f intersection = computeIntersection(line1, line2); if (intersection.x >= 0) { std::cout << "交点坐标: (" << intersection.x << ", " << intersection.y << ")" << std::endl; } else { std::cout << "两直线平行或重合,无交点" << std::endl; } return 0; }
4. 特殊情况处理
-
平行直线:
-
检查行列式 DD 是否接近 0(如
std::abs(D) < 1e-6
)。 -
若平行,可进一步判断是否重合(检查点是否在另一条直线上)。
-
-
数值稳定性:
-
使用浮点数容差(如
1e-6
)避免精度误差。
-
5. 应用场景
-
车道线交点检测:自动驾驶中计算车道消失点。
-
标定板角点计算:相机标定时寻找棋盘格角点。
-
几何测量:工业检测中的物体边缘交点定位。
总结
-
通过解 参数方程联立问题 计算交点。
-
核心步骤:构造矩阵、解线性方程组、验证平行性。
-
代码中需处理 平行/重合 的特殊情况。