直接上代码,原理自行寻找,网上多得很

#include <opencv2/opencv.hpp> // opencv
#include <stdio.h> // 内存操作
#include <stdlib.h>
#include <iostream>using namespace cv;// 二维离散点拟合抛物线的三种写法,三种表达式均为 y = a·X^2 + b·X + c
// 方法一:利用 CvMat
void fitParabola_1(const std::vector<cv::Point2f> &vecPoints, float &a, float &b, float &c) {// 初始化CvMat *matA = cvCreateMat(vecPoints.size(), 3, CV_32FC1);CvMat *matB = cvCreateMat(vecPoints.size(), 1, CV_32FC1);CvMat *matC = cvCreateMat(3, 1, CV_32FC1);// 构造 Afloat *A = (float *)malloc(sizeof(float) * vecPoints.size() * 3);for (int i = 0; i < vecPoints.size(); ++i) {A[3 * i + 0] = vecPoints[i].x * vecPoints[i].x;A[3 * i + 1] = vecPoints[i].x;A[3 * i + 2] = 1;}// 构造 Bfloat *B = (float *)malloc(sizeof(float) * vecPoints.size());for (int i = 0; i < vecPoints.size(); ++i) {B[i] = vecPoints[i].y;}// 赋值cvSetData(matA, A, CV_AUTOSTEP);cvSetData(matB, B, CV_AUTOSTEP);// 求抛物线参数cvSolve(matA, matB, matC, CV_LU);// 返回值a = matC->data.fl[0];b = matC->data.fl[1];c = matC->data.fl[2];// 释放空间if (!A) free(A);if (!B) free(B);
}// 方法二:只能针对三个点进行拟合,多个点要报错,尚且不知道为什么
void fitParabola_2(const std::vector<cv::Point2f> &vecPoints, float &a, float &b, float &c) {// 目前只能用三个点进行拟合,后期修复if (vecPoints.size() != 3) {return;}// 初始化 Matcv::Mat matA(vecPoints.size(), 3, CV_32FC1);cv::Mat matB(vecPoints.size(), 1, CV_32FC1);cv::Mat matC(3, 1, CV_32FC1);// 构造元素for (int i = 0; i < vecPoints.size(); ++i) {matA.at<float>(i, 0) = vecPoints[i].x * vecPoints[i].x;matA.at<float>(i, 1) = vecPoints[i].x;matA.at<float>(i, 2) = 1;}for (int i = 0; i < vecPoints.size(); ++i) {matB.at<float>(i, 0) = vecPoints[i].y;}cv::solve(matA, matB, matC, CV_LU);// 返回值a = matC.at<float>(0, 0);b = matC.at<float>(0, 1);c = matC.at<float>(0, 2);
}// 方法三
// 参考博客:OpenCV最小二乘法:cv::solve函数
// https://blog.csdn.net/qq_20797273/article/details/83930101
void fitParabola_3(const std::vector<cv::Point2f> &vecPoints, float &a, float &b, float &c) {// 代表拟合的是二次方程,取 3 则为三次曲线样条int pow_number = 2;// 离散点个数int N = vecPoints.size();// 构造 Xcv::Mat X = cv::Mat::zeros(pow_number + 1, pow_number + 1, CV_64FC1);for (int i = 0; i < pow_number + 1; i++) {for (int j = 0; j < pow_number + 1; j++) {for (int k = 0; k < N; k++) {X.at<double>(i, j) = X.at<double>(i, j) + std::pow(vecPoints[k].x, i + j);}}}// 构造 Ycv::Mat Y = cv::Mat::zeros(pow_number + 1, 1, CV_64FC1);for (int i = 0; i < pow_number + 1; i++) {for (int k = 0; k < N; k++) {Y.at<double>(i, 0) = Y.at<double>(i, 0) + std::pow(vecPoints[k].x, i) * vecPoints[k].y;}}// 求解 Acv::Mat A = cv::Mat::zeros(pow_number + 1, 1, CV_64FC1);cv::solve(X, Y, A, CV_LU/*DECOMP_LU*/);// 输出结果,如果是三次表达式,则继续倒着往回取值a = A.at<double>(2, 0);b = A.at<double>(1, 0);c = A.at<double>(0, 0);
}int main() {// 随机新建离散点std::vector<cv::Point2f> vecPoints;vecPoints.emplace_back(1, 1);vecPoints.emplace_back(7, 6);vecPoints.emplace_back(2, 8);vecPoints.emplace_back(10, 36);// 分别测试拟合函数{float a, b, c;fitParabola_1(vecPoints, a, b, c);cout << a << " " << b << " " << c << endl;int x = 2;std::cout << "fitParabola_1 - y = " << a *x *x + b *x + c << std::endl;}{// 注意:方法二只能针对三个点,点多要崩溃,正在解决中//float a, b, c;//fitParabola_2(vecPoints, a, b, c);//cout << a << " " << b << " " << c << endl;//int x = 2;//std::cout << "fitParabola_2 - y = " << a * x * x + b * x + c << std::endl;}{float a, b, c;fitParabola_3(vecPoints, a, b, c);cout << a << " " << b << " " << c << endl;int x = 2;std::cout << "fitParabola_3 - y = " << a *x *x + b *x + c << std::endl;}return 0;
}

运行结果

OpenCV 拟合抛物线精简版相关推荐

  1. 应用统计432考研复试复试提问总结精简版【一】

    一.区间估计与假设检验的联系与区别 联系:二者利用样本进行推断,都属于推断统计 区别: 原理: 前者是基于大概率,后者基于小概率: 统计量:前者是构造枢轴量(不含未知参数,分布明确),后者是检验统计量 ...

  2. webview页面和壳通信的库(精简版)

    //PG精简版 (function() {var PG ={iosBridge:null,callbackId:0,callbacks: [],commandQueue: [],commandQueu ...

  3. [导入]金山词霸2005精简版下载地址

    软件简介: 金山词霸 2005 精简版 欢迎使用金山公司著名产品金山词霸的最新版本<金山词霸 2005>. 金山词霸2005融合了英语培训的旗舰品牌洋话连篇视频词库,同时采用国内领先的Sm ...

  4. 微信小程序实战之百思不得姐精简版

    为什么80%的码农都做不了架构师?>>>    微信小程序基本组件和API已撸完,总归要回到正题的,花了大半天时间做了个精简版的百思不得姐,包括段子,图片,音频,视频,四个模块.这篇 ...

  5. 打造精简版Linux-mini

    Linux系统的核心就是它的内核,所有的Linux系统采用的内核都是相同的,唯一不同的就是除了内核以外的服务以及应用的软件不同而已.那麽可以根据Linux的这一特点,我们可以根据自己的需求打造属于自己 ...

  6. [异常解决] ubuntu上安装虚拟机遇到的问题(vmware坑了,virtual-box简单安装,在virtual-box中安装精简版win7)

    [异常解决] ubuntu上安装虚拟机遇到的问题(vmware坑了,virtual-box简单安装,在virtual-box中安装精简版win7) 参考文章: (1)[异常解决] ubuntu上安装虚 ...

  7. Vue精简版风格指南

    前面的话 Vue官网的风格指南按照优先级(依次为必要.强烈推荐.推荐.谨慎使用)分类,且代码间隔较大,不易查询.本文按照类型分类,并对部分示例或解释进行缩减,是Vue风格指南的精简版 组件名称 [组件 ...

  8. 使用 Microsoft .NET Framework 精简版中的 MessageWindow 类

     使用 Microsoft .NET Framework 精简版中的 MessageWindow 类 收藏 Alex Yakhnin IntelliProg, Inc. 2003年3月 适用于:    ...

  9. FCKeditor 2.6 精简版

    来自:http://www.sablog.net/blog/fckeditor-26-lite-one/ 该版本基于 fckeditor 2.6 修改,旨在提高加载速度,删除不常用的功能,达到精简和优 ...

最新文章

  1. java高位转低位注意事项,int转 short/byte溢出过程
  2. 洛谷 P2746 [USACO5.3]校园网Network of Schools (Tarjan,SCC缩点,DAG性质)
  3. 电缆的验证、鉴定和认证应该选择什么测试工具
  4. jzoj3844-统计损失【树形dp,换根法】
  5. Java 监听器,国际化
  6. java 分享巧克力_[leetcode 双周赛 11] 1231 分享巧克力
  7. linux 命令行使用wget下载百度云资源
  8. ACM_基础知识(二)
  9. OpenShift 4 Tekton - Tekton实现包含Gogs+SonaQube+Nexus+Report+WebHook的Pipeline
  10. 【jQuery笔记Part2】04-jQuery淡入淡出动画右下角广告案例
  11. We change lives !
  12. 用javascript实现以下功能!_用python80行代码实现一个微信消息撤回捕捉功能
  13. 如何在Shell脚本中使用if-else?
  14. UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xb4 in position 176: in xxxx
  15. 美科学家研发能从干燥的沙漠空气中造水的新设备
  16. 转:FAMI上的满分游戏
  17. ubuntu下安装搜狗输入法
  18. 服务器数据恢复案例:FreeNAS数据恢复过程记录
  19. 深入理解Magento - 第五章 – Magento资源配置
  20. worldpress 添加网站关键词和描述

热门文章

  1. Android提交应用市场
  2. 社交分享(facebook分享、twitter分享、link分享、google分享)
  3. pip找不到的解决方法
  4. HTML--样式属性
  5. python 爬虫基础学习
  6. python乘法表图片_python的乘法表
  7. 畅游星河的炫彩手柄,配置也不简单,北通阿修罗2Pro上手
  8. 实时操作系统μCOS-II在LPC2210上的移植研究与实现
  9. JavaScript设计了3D六面魔方,实现了魔方的动画
  10. WPF(一) WPF基本控件与布局