【一种用opencv实现高斯曲线拟合的方法】

背景:

项目中需要实现数据的高斯拟合,进而提取数据中标准差,手头只有opencv库,经过资料查找验证,总结该方法。

基础知识:

1、opencv中solve可以实现对矩阵参数的求解;
2、线的拟合就是对多项式参数求解的过程,多项式可表示为矩阵形式;
3、高斯公式中的指数幂,可以通过取对数的方式转变成多项式的形式;
求解思路:
高斯公式->多项式公式->矩阵参数->调用solve求解;

实现过程及代码

1、确定所选的高斯公式形式

G(x)=a*exp(-((x-b)/c)^2);

2、对于给定的输入x1 ~ xn,有对输出y1 ~ yn。可以形成如下等式:

高斯公式及等式组

对等式左右两边取对数,并进行变换,可形成如下形式
对等式左右取自然对数

在这里插入图片描述
这里,就形成了AX^2+BX+C=Y的形式,其中
在这里插入图片描述
用A,B,C替换后后,原等式可写作
在这里插入图片描述
此时,我们只需要计算出A,B,C的值,再通过ABC与abc的关系即可得到abc的值。(请读者自行推导abc的公式,或见代码部分)

得到如上的多项式的形式后,直接构造参数矩阵,调用cv::solve(X,Y,A‘)接口,即可得到参数矩阵A’,其中即含有A,B,C的值。

上代码:

基础定义:

typedef struct StructMultinomialParamt
{double dB0;//多项式拟合的参数,数字表示幂次double dB1;double dB2;
}S_MULTNMNL_PARAMT;
typedef struct StructGaussParamT
{double dA;//指定的高斯参数double dB;//中心点double dC;//标准差
}S_GAUS_PARAMT;
void Gauss(S_GAUS_PARAMT sGsParamm, cv::Mat mX, cv::Mat& mY)
{cv::Mat mRslt = Mat::zeros(mX.size(), mX.type());double dx = 0;for (double i = 0.; i < mX.cols; i++){for (double j = 0.; j < mX.rows; j++){dx = mX.at<double>(j, i);mRslt.at<double>(j, i) = sGsParamm.dA * exp(-(pow((dx - sGsParamm.dB) / sGsParamm.dC, 2)));}}mY = mRslt;return;
}

高斯参数求解函数

void GaussFitT(cv::Mat mX, cv::Mat mY, S_GAUS_PARAMT* psGsParamm)
{//step1 构造参数矩阵mx与mycv::Mat X = Mat::zeros(mX.rows, 3, CV_64FC1);for (size_t i = 0; i < mX.rows; i++){for (size_t J = 0; J < 3; J++){X.at<double>(i, J) = pow(mX.at<double>(i, 0), 2 - J);}}cv::log(mY, mY);//对结果取对数//step2 多项式拟合cv::Mat A;//参数矩阵cv::solve(X, mY, A, cv::DECOMP_SVD);S_MULTNMNL_PARAMT sBparam;sBparam.dB2 = A.at<double>(0);sBparam.dB1 = A.at<double>(1);sBparam.dB0 = A.at<double>(2);//step3 高斯参数计算ABC-》abcpsGsParamm->dA = exp(sBparam.dB0 - pow(sBparam.dB1, 2) / (4 * sBparam.dB2));psGsParamm->dB = -sBparam.dB1 / (2 * sBparam.dB2);psGsParamm->dC = sqrt(-1 / sBparam.dB2);return;
}

# 测试代码

double dX[50];//输入数据X
double dY[50];//输入数据Y
std::vector<cv::Point> pointsOri;for (int i = 0; i < 50; i++)
{dX[i] = double(i);dY[i] = -0.5 * pow((dX[i] - 25), 2) + 320 + i;pointsOri.push_back(cv::Point(dX[i], dY[i]));
}
//转换成求解函数输入需要的数据格式
cv::Mat mGsInputX = Mat::zeros(50, 1, CV_64FC1);
cv::Mat mGsInputY = Mat::zeros(50, 1, CV_64FC1);
for (size_t i = 0; i < 50; i++)
{mGsInputX.at<double>(i) = dX[i];mGsInputY.at<double>(i) = dY[i];
}S_GAUS_PARAMT sGsParamm;//求解结果
GaussFitT(mGsInputX, mGsInputY, &sGsParamm);//结果对比
Mat mGsOutputY;
Gauss(sGsParamm, mGsInputX, mGsOutputY);
std::vector<cv::Point> pointsNew;//拟合结果
for (int i = 0; i < 50; i++)
{pointsNew.push_back(cv::Point(dX[i], mGsOutputY.at<double>(i)));
}
cv::Mat img(450, 60, CV_8UC3, cv::Scalar(0, 0, 0));
cv::polylines(img, std::vector<std::vector<cv::Point>>{pointsOri}, false, cv::Scalar(0, 0, 255), 2);
cv::polylines(img, std::vector<std::vector<cv::Point>>{pointsNew}, false, cv::Scalar(255, 255, 255), 0.5);// 显示图像
cv::imshow("Line Chart", img);
cv::waitKey(0);

运行输出

在这里插入图片描述

红色的为原始数据分布,白色的为拟合计算结果。
而我需要的标准差,则为sGsParamm.dC。

参考:https://blog.csdn.net/guangjie2333/article/details/115629152
https://blog.csdn.net/KYJL888/article/details/103073956
https://blog.csdn.net/qq_35097289/article/details/103910984

后记:

调用solve的接口求解时,OPENCV提供了以下六种方式以对应不同的情况。对于多项式的求解,也可以采用最小二乘法的逼近,不再调用solve方法,这块后面再填坑吧。

cv::DECOMP_LU 高斯消元法(LU分解)
cv::DECOMP_SVD 奇异值分解(SVD)
cv::DECOMP_CHOLESKY 对于对称正定矩阵
cv::DECOMP_EIG 特征值分解,只用于对称矩阵
cv::DECOMP_QR QR因式分解
cv::DECOMP_NORMAL 可选附加标志,表示要求解标准方程

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

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

相关文章

【23-24 秋学期】NNDL 作业11 LSTM

目录 习题6-4 推导LSTM网络中参数的梯度&#xff0c; 并分析其避免梯度消失的效果 习题6-3P 编程实现下图LSTM运行过程 &#xff08;一&#xff09;numpy实现 &#xff08;二&#xff09;使用nn.LSTMCell实现 &#xff08;三&#xff09; 使用nn.LSTM实现 总结 &#x…

dysmsapi

dysmsapi DY - SMS - API 短信服务接口 短信服务_SDK中心-阿里云OpenAPI开发者门户 <!-- 阿里dayu sms api短信群发接口 --><!-- https://mvnrepository.com/artifact/com.aliyun/dysmsapi20170525/2.0.24 --><dependency><groupId>com.aliyun&l…

Java EE 网络之网络初识

文章目录 1. 网络发展史1.1 独立模式1.2 网络互连1.3 局域网 LAN1.4 广域网 WAN 2. 网络通信基础2.1 IP 地址2.2 端口号2.3 认识协议2.4 五元组2.5 协议分层2.5.1 什么是协议分层2.5.2 分层的作用2.5.3 OSI七层协议2.5.4 TCP/IP五层协议2.5.5 网络设备所在分层 2.6 分装和分用 …

Leetcode的AC指南 —— 链表:24. 两两交换链表中的节点

摘要&#xff1a; Leetcode的AC指南 —— 链表&#xff1a;24. 两两交换链表中的节点。题目介绍&#xff1a;给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能…

【OpenHarmony 北向应用开发】ArkTS语言入门(构建应用页面)

ArkTS语言入门 在学习ArkTS语言之前&#xff0c;我们首先需要一个能够编译并运行该语言的工具 DevEco Studio。 了解ArkTS ArkTS是OpenHarmony优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript&#xff08;简称TS&#xff09;生态基础上做了进一步扩展&#xff0c;继…

【MyBatis-Plus】常用的插件介绍(乐观锁、逻辑删除、分页)

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于MyBatis-Plus的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.为什么要使用MyBatis-Plus中的插…

【C语言】随机数生成详解,手把手教你,保姆级!!!

目录 rand函数 srand函数 time函数 设置随机数范围 拓展--猜数字游戏 总结 rand函数 C语⾔提供了⼀个函数叫 rand&#xff0c;这函数是可以⽣成随机数的&#xff0c;函数原型如下所⽰ int rand (void); rand函数会返回⼀个伪随机数&#xff0c;这个随机数的范围是在0~RAN…

Linux(操作系统)面经——part 1(持续更新中......)

1、说一说常用的 Linux 命令 mkdir创建文件夹&#xff0c;touch创建文件&#xff0c;mv移动文件内容或改名 rm-r 文件名&#xff1a;删除文件 cp拷贝&#xff1a;cp 文件1 文件2&#xff0c;cp-r跨目录拷贝 cp-r 路径1 路径2 vi 插入 &#xff1a;wqb保存退出 :q!强制退出…

【Axure教程】区间评分条

区间评分条是一种图形化的表示工具&#xff0c;用于展示某一范围内的数值或分数&#xff0c;并将其划分成不同的区间。这种评分条通常用于直观地显示数据的分布或某个指标的表现。常用于产品评价、调查和反馈、学术评价、健康评估、绩效评估、满意度调查等场景。 所以今天作者…

DOM树和DOM对象与JS关系的深入研究

const和let使用说明 var不好用&#xff0c;我们如果用变量都是用let&#xff0c;如果用常量乃是不变的量&#xff0c;我们用const&#xff0c;见let const知变量是否可变。比如一个常量在整个程序不会变&#xff0c;但是你用let&#xff0c;是可以的。但是let最好与内部变量改…

《洛谷深入浅出进阶篇》简单数据结构

本篇文章内容如下&#xff0c;请耐心观看&#xff0c;将持续更新。 简单数组 简单栈 简单队列 简单链表 简单二叉树 简单集合 图的基本概念 二叉堆 线段树 树状数组与字典树 线段树进阶 简单数组&#xff1a; STL可变数组 vector " 我们首先要知道这个容器有什…

Java多线程编程学习

1 线程的概念 多线程是指同一个程序同时存在多个“执行体”&#xff0c;它们可以同时工作 1.1 进程的概念 一次程序的每一次运行都叫做进程&#xff08;一个进程可以包含多个线程 1.2 线程的概念 多线程是指一个程序中多段代码同时并发进行 1.3 主线程的概念 JavaMain中的线程就…

Python语言学习笔记之十(字符串处理)

本课程对于有其它语言基础的开发人员可以参考和学习&#xff0c;同时也是记录下来&#xff0c;为个人学习使用&#xff0c;文档中有此不当之处&#xff0c;请谅解。 字符串处理&#xff1a;以实现字符串的分割、替换、格式化、大小写转换&#xff0c;Python字符串处理是指对Py…

人工智能知识蒸馏:模型精简与迁移的奇妙之旅

导言 在人工智能领域&#xff0c;知识蒸馏作为一种模型精简和知识迁移的技术手段&#xff0c;逐渐成为提高模型效能和适应更广泛场景的关键工具。知识蒸馏是近年来在深度学习领域备受瞩目的技术&#xff0c;其通过将大模型的知识传递给小模型&#xff0c;旨在实现模型的轻量化与…

docker-compose Install gitea

gitea 前言 Gitea 是一个轻量级的 DevOps 平台软件。从开发计划到产品成型的整个软件生命周期,他都能够高效而轻松的帮助团队和开发者。包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD。它与 GitHub、Bitbucket 和 GitLab 等比较类似。 Gitea 最初是从 Gogs 分支而来…

交友网站的设计与实现(源码+数据库+论文+开题报告+说明文档)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

TSINGSEE青犀基于opencv的安全帽/反光衣/工作服AI检测算法自动识别及应用

安全帽/反光衣/工作服自动识别检测算法可以通过opencvyolo网络对现场画面中人员穿戴着装进行实时分析检测&#xff0c;判断人员是否穿着反光衣/安全帽。在应用场景中&#xff0c;安全帽/反光衣/工作服检测应用十分重要&#xff0c;通过对人员的规范着装进行实时监测与预警&…

CloudFlare 优选ip 和 优选域名的获取方法

1.CloudFlare优选IP网站:【链接直达】 2.CloudFlare 优选IP工具&#xff1a;【开源软件】 3.CloudFlare 优选域名&#xff1a;【GitHub开源工具】 4.CF优选域名推荐&#xff1a; time.cloudflare.com shopify.com time.is icook.hk icook.tw ip.sb japan.com malaysia.com rus…

YOLOV8:最新探测物体状态综合指南

YLOLV8是最新的以YOO为基础的物体检测模型,提供最先进的性能。 利用前几部《yolo》,yolov8更快速更准确&#xff0c;同时为训练模式提供统一的框架 物体检测实例分割影像分类 到编写本文件时,许多功能还没有被添加到超催化剂YLOLV8存储库中。这包括训练有素的模型的一整套导…

Axure元件的介绍使用以及登录界面和个人简历的绘制

目录 一、Axure元件介绍 1.1 简介 1.2 特点 1.3 元件操作 二、基本元件的使用 2.1 矩形和圆形 2.2 图片 2.2.1 图片元件特点 2.2.2 具体操作 2.3 占位符 2.3.1 使用规范方法举例 2.4 文本元件 2.4.1 图示 2.5 热区 2.5.1 图示 2.5.2 热区辅助页面排版 2.6 线段…