OpenCV中直线、曲线和圆的拟合方法

一、直线拟合

  1. 最小二乘法直线拟合(cv::fitLine

    • 原理‌:通过最小化点到直线的垂直距离平方和,计算最优直线参数‌。
    • 函数参数说明‌:
      void cv::fitLine(InputArray points,    // 输入点集(2D或3D)OutputArray line,    // 输出直线参数(2D为Vec4f,3D为Vec6f)int distType,        // 距离类型(如DIST_L2、DIST_L1)double param,        // 距离权重参数(通常设为0)double reps,         // 径向精度阈值(推荐0.01)double aeps          // 角度精度阈值(推荐0.01)
      );
      ‌distType‌:
      DIST_L2:对噪声敏感,适合无异常值数据‌。
      DIST_HUBER:鲁棒性较强,可抑制部分异常点‌。
      
    • 应用场景‌:适用于高精度直线参数提取(如工业检测中的边缘对齐)‌。

二、曲线拟合

  1. 多项式曲线拟合

    • 原理‌:使用最小二乘法拟合多项式曲线(如二次、三次多项式),通过解线性方程组获取系数‌。
    • 实现步骤‌:
      • 调用cv::solve解线性方程组,生成多项式系数矩阵‌。
      • 根据系数生成连续曲线点集,用于绘制拟合曲线‌。
    • 参数限制‌:多项式阶数需满足阶数 ≤ 数据点数 - 1‌。
  2. 基于Numpy的快速拟合(np.polyfit

    • 优势‌:简化多项式拟合流程,直接生成多项式方程(需结合OpenCV绘图)‌。
    • 示例‌:
      coefficients = np.polyfit(x_points, y_points, degree) # 生成多项式系数

三、圆拟合

  1. 二维圆拟合

    • 原理‌:通过最小二乘法或RANSAC算法,计算圆心坐标和半径‌。
    • 实现函数‌:OpenCV未提供直接接口,需自行实现或结合第三方库(如scikit-learn)‌。
  2. 三维空间圆拟合

    • 挑战‌:需处理三维点云数据,通常通过投影到二维平面或使用迭代优化方法实现‌。

四、代码

1.‌最小二乘法直线拟合
#include <opencv2/opencv.hpp>
#include <vector>using namespace cv;
using namespace std;int main() {// 模拟输入点集(可替换为实际图像边缘点)vector<Point2f> points = {{50, 100}, {100, 150}, {150, 200}, {200, 250}};// 直线拟合Vec4f lineParams;fitLine(points, lineParams, DIST_L2, 0, 0.01, 0.01);// 解析直线参数:vx, vy 是方向向量,x0, y0 是直线上一点float vx = lineParams;float vy = lineParams;float x0 = lineParams;float y0 = lineParams;// 计算直线端点(延伸100像素)Point pt1(x0 - 100*vx, y0 - 100*vy);Point pt2(x0 + 100*vx, y0 + 100*vy);// 可视化Mat img = Mat::zeros(300, 300, CV_8UC3);for (const auto& p : points) {circle(img, p, 3, Scalar(0, 255, 0), FILLED); // 绘制输入点}line(img, pt1, pt2, Scalar(0, 0, 255), 2); // 绘制拟合直线imshow("Line Fitting", img);waitKey(0);return 0;
}
2. 曲线拟合
#include <opencv2/opencv.hpp>
#include <vector>
#include <cmath>using namespace cv;
using namespace std;int main() {// 输入点集(二次曲线y = ax^2 + bx + c 比如:y = 0.5x² + 3x + 10 的采样)vector<Point2f> points;for (int x = 0; x <= 20; x += 2) {float y = 0.5*pow(x,2) + 3*x + 10;points.emplace_back(x*10, y*10); // 放大坐标便于显示}// 构建矩阵方程 Ax = bMat A(points.size(), 3, CV_32F);Mat b(points.size(), 1, CV_32F);for (size_t i = 0; i < points.size(); i++) {float x = points[i].x;A.at<float>(i, 0) = x*x;A.at<float>(i, 1) = x;A.at<float>(i, 2) = 1;b.at<float>(i) = points[i].y;}// 解方程 (A^T * A) * coeff = A^T * bMat coeff;solve(A, b, coeff, DECOMP_NORMAL | DECOMP_SVD);// 生成拟合曲线点vector<Point> curvePoints;for (int x = 0; x <= 200; x += 2) {float y = coeff.at<float>(0)*x*x + coeff.at<float>(1)*x + coeff.at<float>(2);curvePoints.emplace_back(x, cvRound(y));}// 可视化Mat img = Mat::zeros(800, 800, CV_8UC3);for (const auto& p : points) {circle(img, p, 5, Scalar(0, 255, 0), FILLED);}polylines(img, curvePoints, false, Scalar(0, 0, 255), 2);imshow("Curve Fitting", img);waitKey(0);return 0;
}

关键点‌:

  • 使用 solve() 解多项式方程组
  • 支持任意次多项式(需修改矩阵维度)
  • 通过 DECOMP_SVD 提高数值稳定性

在C++中,我们可以使用Eigen库或手动实现最小二乘法:

#include <iostream>
#include <vector>
#include <Eigen/Dense>struct Point {double x, y;
};int main() {std::vector<Point> points = {{1, 2}, {2, 5}, {3, 10}, {4, 17}};int n = points.size();Eigen::MatrixXd A(n, 3); // 二次方程有3个参数a, b, cEigen::VectorXd b(n); // y值Eigen::Vector3d coeffs; // 系数向量for (int i = 0; i < n; ++i) {A(i, 0) = points[i].x * points[i].x; // x^2A(i, 1) = points[i].x;               // xA(i, 2) = 1;                        // 1 (constant term)b(i) = points[i].y;                // y值}coeffs = A.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b);std::cout << "Coefficients: " << coeffs.transpose() << std::endl; // a, b, creturn 0;
}
3. 圆拟合
#include <opencv2/opencv.hpp>
#include <vector>using namespace cv;
using namespace std;int main() {// 生成模拟点集(实际应用中可通过findContours获取轮廓)vector<Point2f> points;for (int angle = 0; angle < 360; angle += 30) {float radian = angle * CV_PI / 180;points.emplace_back(100 + 50*cos(radian), 100 + 50*sin(radian));}// 最小包围圆拟合Point2f center;float radius;minEnclosingCircle(points, center, radius);// 可视化Mat img = Mat::zeros(200, 200, CV_8UC3);for (const auto& p : points) {circle(img, p, 3, Scalar(0, 255, 0), FILLED);}circle(img, center, cvRound(radius), Scalar(0, 0, 255), 1);imshow("Circle Fitting", img);waitKey(0);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/37482.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot实现调用百度ocr实现身份识别+二要素校验

一、技术选型 OCR服务&#xff1a;推荐使用百度AI 二、实现 1.注册一个服务 百度智能云控制台https://console.bce.baidu.com/ai-engine/ocr/overview/index?_1742309417611 填写完之后可以获取到app-id、apiKey、SecretKey这三个后面文件配置会用到 2、导入依赖 <!-- …

【数据分享】2000—2024年我国乡镇的逐月归一化植被指数(NDVI)数据(Shp/Excel格式)

之前我们分享过2000—2024年我国省市县三级逐月归一化植被指数&#xff08;NDVI&#xff09;数据&#xff0c;该数据是基于NASA定期发布的MOD13A3数据集中的月度NDVI栅格数据&#xff08;可查看之前的文章获悉详情&#xff09;计算得出。很多小伙伴拿到数据后反馈是否可以处理出…

背包问题——动态规划的经典问题包括01背包问题和完全背包问题

01背包问题&#xff1a;给你多个物品每个物品只能选一次&#xff0c;要你在不超过背包容积&#xff08;或者恰好等于&#xff09;的情况下选择装价值最大的组合。如果没有动态规划的基础其实是很难理解这个问题的&#xff0c;所以看这篇文章之前先去学习一下动态规划的基本思想…

AI Agent系列(七) -思维链(Chain of Thought,CoT)

AI Agent系列【七】 前言一、CoT技术详解1.1 CoT组成1.2 CoT的特点 二、CoT的作用三、CoT的好处四、CoT适用场景五、CoT的推理结构 前言 思维链(Chain of Thought,CoT)&#xff0c;思维链就是一系列中间的推理步骤(a series of intermediate reasoning steps)&#xff0c;通过…

Docker搭建Testlink教程

1.拉取镜像 打开终端输入命令&#xff1a; #拉取mariadb镜像 docker pull bitnami/mariadb #拉取testlink镜像 docker pull bitnami/testlink-archived 执行结果&#xff1a; 2.运行容器 打开终端输入命令&#xff1a; #创建容器网络 docker network create testlink #查…

考研c语言复习之栈

栈一般出选择题&#xff0c;队列选择题和大题都有 栈&#xff1a;只允许在一端 进行插入或删除操作的线性表即栈顶&#xff08;top) s.top-1时栈为空 向栈中插入元素 s.tops.top1;s.data[s.top]value; 这段代码可以用一行代码代替&#xff1a; s.data[s.top]value; 不懂i和…

C#里使用libxl来合并单元格的例子

操作EXCEL的文件格式是常用的功能&#xff0c; 通过不同的单元格的合并&#xff0c;可以生成不同的表格。 如下图所示&#xff1a; 采用libxl来创建上面的EXCEL&#xff0c;使用下面的代码来实现&#xff1a; private void button8_Click(object sender, EventArgs e) {var …

大屏技术汇集【目录】

Cesium 自从首次发布以来&#xff0c;经历了多个版本的迭代和更新&#xff0c;每个版本都带来了性能改进、新功能添加以及对现有功能的优化。以下是 Cesium 一些重要版本及其主要特点&#xff1a; 主要版本概述 Cesium 1.0 (2012年) 初始版本发布&#xff0c;确立了Cesium作为…

《深度学习》——YOLOv3详解

文章目录 YOLOv3简介YOLOv3核心原理YOLOv3改进YOLOv3网络结构 YOLOv3简介 YOLOv3&#xff08;You Only Look Once, version 3&#xff09;是一种先进的实时目标检测算法&#xff0c;由 Joseph Redmon 和 Ali Farhadi 开发。它在目标检测领域表现出色&#xff0c;具有速度快、精…

websocket中spring注入失效

一个null指针引发的思考 websocket中spring注入失效 一个null指针引发的思考场景代码SpringBoot入口类配置类websocket类 问题排查问题1&#xff1a;问题2&#xff1a; 反思解决方案一&#xff1a;方案二&#xff1a;方案三&#xff1a;方案四&#xff1a; 场景 首页有个webso…

QT开发(4)--各种方式实现HelloWorld

目录 1. 编辑框实现 2. 按钮实现 前面已经写过通过标签实现的了&#xff0c;所以这里就不写了&#xff0c;通过这两个例子&#xff0c;其他的也是同理 1. 编辑框实现 编辑框分为单行编辑框&#xff08;QLineEdit&#xff09;双行编辑框&#xff08;QTextEdit&#xff09;&am…

自由学习记录(45)

顶点片元着色器&#xff08;important&#xff09; 1.需要在Pass渲染通道中编写着色器逻辑 2.可以使用cG或HLSL两种shader语言去编写Shader逻辑 3.代码量较多&#xff0c;灵活性较强&#xff0c;性能消耗更可控&#xff0c;可以实现更多渲染细节 4.适用于光照处理较少&#xf…

内存管理(C++篇)

前言 我们在C语言阶段学习过内存管理的相关操作和知识&#xff0c;比如说malloc&#xff0c;calloc等内存开辟函数&#xff0c;但我们在学的时候会发现&#xff0c;使用这些函数还是相对来说比较冗杂的&#xff0c;那么今天我们来学习C语言中相关的内存管理操作&#xff0c;相信…

母婴电商企业案例:日事清驱动项目管理执行与OKR目标管理的流程自动化实践

一、关于科木电商 “小鹿豆豆”&#xff0c;一个年轻的品牌&#xff0c;近期在无论是淘宝、拼多多还是抖音电商平台&#xff0c;都成了亮眼的爆品。这个由绵阳科木电子商务有限公司推出的新品牌&#xff0c;以其高品质的保湿云柔巾迅速赢得了母婴护理市场的青睐&#xff0c;特别…

图数据库Neo4j和JDK安装与配置教程(超详细)

目录 前言 一、Java环境配置 &#xff08;一&#xff09;JDK的下载与安装 &#xff08;二&#xff09;JDK环境配置 &#xff08;三&#xff09;检测JDK17是否配置成功 二、Neo4j的安装与配置 &#xff08;一&#xff09;Neo4j的下载与安装 &#xff08;二&#xff09;N…

git原理与常用命令及其使用

认识工作区、暂存区、版本库 ⼯作区&#xff1a;是在电脑上你要写代码或⽂件的⽬录。 暂存区&#xff1a;英⽂叫 stage 或 index。⼀般存放在 .git ⽬录下的 index ⽂件&#xff08;.git/index&#xff09;中&#xff0c;我们 把暂存区有时也叫作索引&#xff08;index&#xf…

Web-Machine-N7靶机通关攻略

获取靶机ip arp-scan -l 端口扫描 nmap xxxx 访问80端口发现没用 扫描目录 gobuster dir -u http:/192.168.117.160 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium,txt -x php,html,txt ,zip 打开exploit.html 点击F12&#xff0c;修改localhost为靶机ip&#…

2025-03-21 Unity 网络基础3——TCP网络通信准备知识

文章目录 1 IP/端口类1.1 IPAddress1.2 IPEndPoint 2 域名解析2.1 IPHostEntry2.2 Dns 3 序列化与反序列化3.1 序列化3.1.1 内置类型 -> 字节数组3.1.2 字符串 -> 字节数组3.1.3 类对象 -> 字节数组 3.2 反序列化3.2.1 字节数组 -> 内置类型3.2.2 字节数组 -> 字…

Java-servlet(七)详细讲解Servlet注解

Java-servlet&#xff08;七&#xff09;详细讲解Servlet注解 前言一、注解的基本概念二、Override 注解2.1 作用与优势2.2 示例代码 三、Target 注解3.1 定义与用途3.2 示例代码 四、WebServlet 注解4.1 作用4.2 示例代码 五、反射与注解5.1 反射的概念5.2 注解与反射的结合使…

nginx 反向代理 ubuntu

关键字 Nginx&#xff0c;正向代理&#xff0c;方向代理&#xff0c;博客建站 背景环境 我在搭建个人博客的过程中遇到一个问题&#xff0c;我的博客服务的端口是1313&#xff0c;我的域名是qinyangx.top。我希望能够通过qinyangx.top直接访问到服务器上1313端口的博客服务。…