opencv线条拟合_【OpenCV3】直线拟合--FitLine()函数详解

本文详细介绍了OpenCV中的FitLine()函数,用于二维和三维直线的拟合。该函数接受点集作为输入,输出拟合直线的方向向量和一个线上的点。距离类型和参数影响拟合的质量,例如DIST_L2使用欧几里得距离。示例代码展示了如何使用FitLine()函数并绘制拟合结果。
摘要由CSDN通过智能技术生成

一、FitLine()函数原型

CV_EXPORTS_W voidfitLine(

InputArray points,//待输入点集(一般为二维数组或vector点集)

OutputArray line, //输出点集(一个是方向向量,另一个是拟合直线上的点)(Vec4f(2d)或Vec6f(3d)的vector)

int distType, // 距离类型

double param, // 距离参数

doublereps,       // 径向的精度参数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|

第四个参数是距离参数,跟所选的距离类型有关,值可以设置为0,cv::fitLine()函数本身会自动选择最优化的值

第五、六两个参数用于表示拟合直线所需要的径向和角度精度,通常情况下两个值均被设定为1e-2。

下面,从一个具体的例子来看cv::Line()实际拟合的效果。

#include #include#include

using namespacestd;using namespacecv;intmain()

{//创建一个用于绘制图像的空白图

cv::Mat image = cv::Mat::zeros(480, 640, CV_8UC3);//输入拟合点

std::vector<: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 <<: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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值