一, FitLine()函数原型
- CV_EXPORTS_W void fitLine(
- InputArray points, // 待输入点集(一般为二维数组或 vector 点集)
- OutputArray line, // 输出点集 (一个是方向向量, 另一个是拟合直线上的点)(Vec4f(2d) 或 Vec6f(3d)的 vector)
- int distType, // 距离类型
- double param, // 距离参数
- double reps, // 径向的精度参数
- double aeps ); // 角度精度参数
第一个参数是用于拟合直线的输入点集, 可以是二维点的 cv::Mat 数组, 也可以是二维点的 STL vector.
第二个参数是输出的直线, 对于二维直线而言类型为 cv::Vec4f, 对于三维直线类型则是 cv::Vec6f, 输出参数的前半部分给出的是直线的方向, 而后半部分给出的是直线上的一点(即通常所说的点斜式直线).
第三个参数是距离类型, 拟合直线时, 要使输入点到拟合直线的距离和最小化(即下面公式中的 cost 最小化), 可供选的距离类型如下表所示, ri 表示的是输入的点到直线的距离.
- CV_DIST_USER =-1, /* User defined distance */
- CV_DIST_L1 =1, /* distance = |x1-x2| + |y1-y2| */
- CV_DIST_L2 =2, /* the simple euclidean distance */
- CV_DIST_C =3, /* distance = max(|x1-x2|,|y1-y2|) */
- CV_DIST_L12 =4, /* L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1)) */
- CV_DIST_FAIR =5, /* distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998 */
- CV_DIST_WELSCH =6, /* distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846 */
- CV_DIST_HUBER =7 /* distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345 */
第四个参数是距离参数, 跟所选的距离类型有关, 值可以设置为 0,cv::fitLine()函数本身会自动选择最优化的值
第五, 六两个参数用于表示拟合直线所需要的径向和角度精度, 通常情况下两个值均被设定为 1e-2.
下面, 从一个具体的例子来看 cv::Line()实际拟合的效果.
- #include <opencv2/opencv.cpp>
- #include <vector>
- #include <iostream>
- using namespace std;
- using namespace cv;
- int main()
- {
- // 创建一个用于绘制图像的空白图
- cv::Mat image = cv::Mat::zeros(480, 640, CV_8UC3);
- // 输入拟合点
- std::vector<cv::Point> points;
- points.push_back(cv::Point(48, 58));
- points.push_back(cv::Point(105, 98));
- points.push_back(cv::Point(155, 160));
- points.push_back(cv::Point(212, 220));
- points.push_back(cv::Point(248, 260));
- points.push_back(cv::Point(320, 300));
- points.push_back(cv::Point(350, 360));
- points.push_back(cv::Point(412, 400));
- // 将拟合点绘制到空白图上
- for (int i = 0; i < points.size(); i++)
- {
- cv::circle(image, points[i], 5, cv::Scalar(0, 0, 255), 2, 8, 0);
- }
- cv::Vec4f line_para;
- cv::fitLine(points, line_para, cv::DIST_L2, 0, 1e-2, 1e-2);
- std::cout << "line_para =" << line_para << std::endl;
- // 获取点斜式的点和斜率
- cv::Point point0;
- point0.x = line_para[2];
- point0.y = line_para[3];
- double k = line_para[1] / line_para[0];
- // 计算直线的端点(y = k(x - x0) + y0)
- cv::Point point1, point2;
- point1.x = 0;
- point1.y = k * (0 - point0.x) + point0.y;
- point2.x = 640;
- point2.y = k * (640 - point0.x) + point0.y;
- cv::line(image, point1, point2, cv::Scalar(0, 255, 0), 2, 8, 0);
- cv::imshow("image", image);
- cv::waitKey(0);
- return 0;
- }
参考链接:(1)https://blog.csdn.net/guduruyu/article/details/69505487
(2)https://blog.csdn.net/qq_29540745/article/details/72779847
来源: https://www.cnblogs.com/hs-pingfan/p/10477937.html