当前位置: 首页 > news >正文

OpenCV图像处理——直线拟合并找出拟合直线的起点与端点

引言

对轮廓进行分析,除了可以对轮廓进行椭圆或者圆的拟合之外,还可以对轮廓点集进行直线拟合。在 OpenCV 中,直线拟合通常是通过 cv::fitLine 函数实现的,该函数采用最小二乘法对一组 2D 或 3D 点进行直线拟合。对于 2D 点集,拟合结果是一个 cv::Vec4f 类型的向量,包含了直线的方向向量和直线上的一个点。这个方向向量可以被转换为直线的斜率和截距,从而得到直线的方程。

OpenCV实现直线拟合的API如下:

void cv::fitLine(InputArray points,OutputArray line,int distType,double param,double reps,double aeps 
)
points表示待拟合的输入点集合
line在二维拟合时候输出的是vec4f类型的数据,在三维拟合的时候输出是vec6f的vector
distType表示在拟合时候使用距离计算公式是哪一种,OpenCV支持如下六种方式:DIST_L1 = 1DIST_L2 = 2DIST_L12 = 4DIST_FAIR = 5DIST_WELSCH = 6DIST_HUBER = 7
param对模型拟合距离计算公式需要参数C,5~7 distType需要参数C
reps与aeps是指对拟合结果的精度要求,一般取0.01

在这里插入图片描述

示例代码

void fit_line_points(std::vector<cv::Point>& points, cv::Point2f& p1, cv::Point2f& p2)
{// 使用 fitLine 拟合直线cv::Vec4f line;fitLine(points, line, cv::DIST_L2, 0, 0.01, 0.01);cv::Point2f pointOnLine(line[2], line[3]); // 直线上的一个点cv::Point2f direction(line[0], line[1]);   // 直线的方向向量// 找到拟合直线方向上投影距离最小和最大的点(计算端点)float t_min = FLT_MAX, t_max = -FLT_MAX;cv::Point2f minPoint, maxPoint;for (const auto& pt : points) {// 投影长度 t = (pt - pointOnLine) · directionfloat t = (pt.x - pointOnLine.x) * direction.x + (pt.y - pointOnLine.y) * direction.y;if (t < t_min) {t_min = t;minPoint = pt;}if (t > t_max) {t_max = t;maxPoint = pt;}}// 使用方向向量扩展点,计算直线的两个顶点p1 = pointOnLine + direction * t_min;p2 = pointOnLine + direction * t_max;
}

调用函数:

int main() 
{// 创建一些示例点vector<Point2f> points = {Point2f(100, 100), Point2f(150, 200), Point2f(200, 300),Point2f(300, 400), Point2f(400, 500), Point2f(500, 600)};// 拟合直线并找到直线的两个顶点LineEndpoints result = fitLineAndFindEndpoints(points);// 打印结果cout << "Endpoint 1: [" << result.endpoint1.x << ", " << result.endpoint1.y << "]" << endl;cout << "Endpoint 2: [" << result.endpoint2.x << ", " << result.endpoint2.y << "]" << endl;// 在图像上绘制这些点和拟合的直线Mat image = Mat::zeros(Size(800, 800), CV_8UC3);for (const auto& pt : points) {circle(image, pt, 5, Scalar(0, 0, 255), FILLED);}line(image, result.endpoint1, result.endpoint2, Scalar(0, 255, 0), 2);circle(image, result.endpoint1, 5, Scalar(255, 0, 0), FILLED);circle(image, result.endpoint2, 5, Scalar(255, 0, 0), FILLED);// 显示结果图像namedWindow("Fitted Line", WINDOW_AUTOSIZE);imshow("Fitted Line", image);waitKey(0);return 0;
}

实现结果:
在这里插入图片描述

代码说明

  1. 点集创建:

    • 首先创建了一组示例点,这些点可以是任意想要拟合的点集。
  2. 拟合直线:

    • cv::fitLine 函数用于对点集进行直线拟合。它返回一个包含直线参数的 Vec4f 向量:
      • line[0]line[1] 是直线的方向向量 (vx, vy)
      • line[2]line[3] 是直线上的一个点 (x0, y0)
  3. 计算最远的两个点:

    • 对于每个点,计算其在拟合直线上的投影长度 t。投影长度 t 计算方式是点到直线上某一点的向量与方向向量的点积。
    • 通过比较 t 值,找到投影最小的点 minPoint 和投影最大的点 maxPoint。这两个点就是距离最远的点。
  4. 绘制直线与最远的点:

    • 使用 line 函数在图像上绘制拟合的直线(连接 minPointmaxPoint)。
    • 使用 circle 函数标记最远的两个点。
  5. 显示结果:

    • 使用 imshow 函数显示结果图像,其中红色点表示原始点集,绿色直线是拟合的直线,蓝色点是距离最远的两个点。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • multimodel ocr dataset
  • 密码学基础---椭圆曲线一文打尽
  • 鸿蒙开发入门day10-组件导航
  • Python办公自动化:使用openpyxl 创建与保存 Excel 工作簿
  • MATLAB 手动实现投影密度法分割建筑物立面 (73)
  • Chart.js:内容、优点及使用方法
  • 常见的排序算法汇总(详解篇)
  • 稚晖君发布5款全能人形机器人,开源创新,全能应用
  • 单体应用spring Task和分布式调度
  • CDN劫持总结
  • MK米客方德推出新一代工业级SD NAND——更长寿命、更高速度、更优功耗
  • 白骑士的C#教学实战项目篇 4.1 控制台应用程序
  • 凹凸纹理概念
  • 定长滑动窗口算法
  • 【SQL】科目种类
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 2019.2.20 c++ 知识梳理
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • Docker容器管理
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • Laravel Telescope:优雅的应用调试工具
  • passportjs 源码分析
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • zookeeper系列(七)实战分布式命名服务
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 对超线程几个不同角度的解释
  • 构建二叉树进行数值数组的去重及优化
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 如何设计一个比特币钱包服务
  • 如何用vue打造一个移动端音乐播放器
  • 实现菜单下拉伸展折叠效果demo
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 正则表达式
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • !!Dom4j 学习笔记
  • "无招胜有招"nbsp;史上最全的互…
  • #WEB前端(HTML属性)
  • $().each和$.each的区别
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (Charles)如何抓取手机http的报文
  • (差分)胡桃爱原石
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (顺序)容器的好伴侣 --- 容器适配器
  • (算法)前K大的和
  • . Flume面试题
  • ../depcomp: line 571: exec: g++: not found
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .net framework4与其client profile版本的区别
  • .Net 代码性能 - (1)