数值分析:多项式的最小二乘法拟合
多项式拟合-最小二乘法
代数角度
最小二乘法使用多项式拟合样本数据,其基本代数原理以下。
假设使用的是m阶多项式拟合,那么在的估计值为:
其误差表示为:
那么对于n个样本点,使用平方和误差量化,该误差就是数据的优化目标,自变量为各阶的权值w,有:
求E(w)极小值,需对其求偏导,为:
有:
权重系数与i无关,可以写成:
同样的,此为一个约束条件,对于m阶的多项式,存在m+1项的偏导联合约束,所以有:
写成矩阵表达式:
C++实现
如下: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869#include <opencv2/opencv.hpp>#include <iostream>#include <math.h>using namespace std;using namespace cv;//样本点 ...
OpenCV C++记录(十四):距离变换与基于标记的分水岭算法
距离变换算法
距离变换算法是基于二值化图像转换,得到与前景输入类似的灰度图,其基本原理是计算前景像素(255)到背景像素(0)的最小距离,背景像素值的距离仍然为0,距离变换算法能简单地在图像生成前景特征,在图像分割、特征提取中有重要作用,此处所说的距离是三种经典距离,在前面文章OpenCV
C++记录(八):Sobel、Scharr、Laplacian、Canny算子简单提过,其数学特征是:
欧氏距离(DIST_L2):
曼哈顿距离(城市距离,DIST_L1):
棋盘距离(切比雪夫距离,DIST_C)
三种距离定义
OpenCV实现
OpenCV提供了距离变换接口,可以计算二值图的前景和背景距离灰度分布情况:
123456void distanceTransform(cv::InputArray src, //输入二值化图 cv::OutputArray dst, //输出距离 int distanceType, //三种类型距离 int maskSize, //掩图大小,一般为3 int ds ...
OpenCV C++记录(十三):角点检测算法与亚像素优化
角点是图像的重要特征,往往比边缘和平坦区域具有更独一无二的特征,例如在拼图时,我们往往会先寻找物体对象的角点,最后再完善边缘和平坦区域,对于图像的特征检测亦是如此,角点检测是重要一环。
Harris角点检测
基本原理
1988年,Chris Harris和Mike
Stephens提出了角点检测的方法,称为Harris角点检测,其基本思想是考虑窗口到各个方向的灰度差异总和,表示为:
窗口权值函数灰度增量函数灰度函数
权值函数既可以是普通窗口,也可以是与中心距离相关的高斯窗口。
其中增量项可以根据二元一阶泰勒展开成偏导项Ix和Iy和二阶无穷小:
故原式等于:
此处令M = ,
可根据其特征值进一步判断某区域是平坦还是出现边缘还是角点,Harris检测响应公式:
此处的特征值可以理解成两个正交方向的变化率,结论如下:
当|R|很大,为角点,因为此时λ1和λ2均很大,说明两个正交方向都有大的变化率;
当|R|很小,为平坦区,此时λ1和λ2都很小,两个正交方向变化率军均很小;
当R<0,
为边缘,说明λ1和λ2其中一个很小,只有一个方向存在变化率 ...
OpenCV C++记录(十二):齐次坐标、相机成像模型与张正友标定
齐次坐标
在视觉处理的一些数学原理中,常常看见齐次坐标的身影。所谓齐次坐标,是在原来笛卡尔坐标的基础上增加一个维度,例如二维笛卡尔坐标(x,y)对应的齐次坐标为(x,y,1),以此类推,三维笛卡尔坐标(x,y,z)对应齐次坐标(x,y,z,1)。之所以使用齐次坐标,首先其能更方便地描述和求解几何关系,再者从2D到3D的变换,使用齐次坐标能表示一些二维空间难以表述的数学关系,例如无限远、两条平行线的交点(透视变换),其能够做到以下事情。
对点、线、平面关系的描述
点在线上、点在面上
一条二维直线的方程可以表示为: : 使用向量表示其系数,为:
所以对于任意点p(x,y),其对应齐次坐标为(x,y,1),p在直线上的充要条件是满足二者内积为0:
同理,对于三维情况,表示空间点p(x,y,z)在平面A上:
二维线交点与共线
齐次坐标还可以方便地表达两条二维直线的交点以及确定两点所在的直线方程,结论是:
1.
两条直线的系数向量叉乘等于其交点的齐次坐标
证明:假设直线、,易知两个系数向量的叉乘得到的向量同时垂直于和,故其内积为0,结合点在线上的充要条件:
...
数值分析:三次样条插值算法(Cubic Spline Interpolation)
龙格现象(Runge Phenomenon)
在对数据进行估计时往往有拟合和插值两种方法,拟合只会尽量估计数据集的整体分布趋势,不会确保经过所有的样本点,而插值会经过所有的样本点,但一般而言线性插值产生折线效果,其一阶导数不连续,往往使用高阶插值,但高阶插值可能产生龙格现象,龙格现象指的是均匀分布的插值点函数阶数升高,在多项式端点处可能造成振荡,产生严重误差,龙格现象的原因剖析详见龙格现象,解决这种现象可以通过引入高斯或切比雪夫插值点,或者使用分段的插值进行解决。
三次样条插值(Cubic
Spline Interpolation)
样条插值源自工程制图,其通过固定的钉子,将柔软的木条固定:
引入数学,木条的函数可以由分段的端点函数进行表示,保证了整体函数的光滑性,三次样条插值在数学上是一个三次分段函数:
可见其有4n个方程参数,但只能建立4n-2个方程.
具体而言,根据函数连续性,n+1个端点,可建立2n个方程(两侧端点只能各建立一个方程):
因为函数光滑,其除两侧外的端点满足二阶导数连续、一阶导数连续,分别建立n-1个方程:
剩下两个条件根据边界 ...
(Private)基于C++ boost与ZeroMQ远程发布订阅远程调用网络设计
103c704d716c2a6b4b59a60c7b698e01e267a92d601a60f130246c8b57cc624a9933f09653cb8ae792d31f011500a065940fb391eecc0e17d2bd57d1fab6c0d1144c1f5c92ed1ba36ff05a279c108cdb29a273c67cdf35956c598ad27624052eaaac6b2338574150321a002a8a0878375ebbe3d163ea7a99f3ce3203c1def7dfa2563feff714e05bb34da4b7a72c21f3aea0edcf962574c062693b88246c17ee094d52dd6b8f042a7fad72d03347641eaa692961827d585413604ae6c348bbee1099a3511768b4c8b51f427356888e316b44a1837d02a04138141fcd6020745f3b738390a3ac6b71866ac3eb080b9aff41640e08c908d7c01 ...
boost库开发笔记(五):boost库杂记
记录了boost库一些特别的设计。
boost::program_options
命令行解析:基本类型支持
boost::program_options可以用于解析命令行参数,常常被用于解析项目运行命令、配置文件、环境变量等到boost::program_options::variables_map,这个map是一个string-boost::program_options::variable_value的键值对集合,variable_value.as<T>()方法能够将其转换到基本数据类型,以及std::vector<T>以及自定义结构体等,见下文。
一个简单实例如下: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748#include <iostream>#include <boost/program_options.hpp>using namespace std;namespace program_op ...
boost库开发笔记(四):boost::property_tree的json与ini封装与解析
boost::property_tree::ptree
boost::property_tree::ptree是一种树结构,其本质相当于(注意这不是定义式):
1234struct basic_ptree{ string data; basic_ptree* next;};
可见其结构上就是一种树/链表,适合用于解析嵌套的键值对文件,如json、ini等。
json
json方法基本没有可参考性,看不看都行,真是脑子被踢了才会学。
json解析
json解析首选仍然是boost::json库,因为其支持类型检查、序列化等,ptree基本只能解析结构相对简单、且知道值类型的(或者类型比较统一的)json结构,了解基本接口即可:
其中get_child表示获取子节点,得到的是一个新的ptree对象,对于一般数据类型,遍历ptree,迭代器是一个pair对象:std::pair<string, property_tree::ptree>,若second为空,意味着无子节点(注意ptree.second.empty成立,指的是ptre ...
boost库开发笔记(三):boost::beast websocket异步网络编程
boost::beast
boost::beast是一个基于boost::asio封装的一个网络编程库,与asio注重网络底层不同,beast专注于搭建Http和WebSocket服务器框架,其完全由C++实现,支持零拷贝、异步、多线程、协程等,性能极高,支持ssl/tls加密等,但它的缺点也来自C++,例如开箱即用的轮子少、编译时间较长、更注重底层使得应用层兼容性一般、较繁杂的错误处理机制。
示例来自官方示例。
同步服务器-客户端
服务器端:比asio中的示例多了几步,首先是使用socket初始化一个websocket的流对象,设置其http响应头:websocket的连接建立是通过http握手开始的:
websocket的http握手
客户端发送消息: 1234GET /index.html HTTP/1.1 #起始行Host: www.example.com #HTTP 头(Header)User-Agent: Mozilla/5.0Accept: text/html
服务器响应: 123HTTP/1.1 200 OK #起始行Content-Type: text/ ...
网络编程库:C++ ZeroMQ学习笔记
ZeroMQ是一个高性能、跨语言的网络编程框架,许多人称其命名为MQ并不准确,因为ZeroMQ已经超越消息队列范畴,完全是一种高抽象的Socket,原生使用C语言进行撰写,随即涵盖到基本几十种的开发语言中,当然包括C++/Java/Go/Python/Rust等。
ZeroMQ在2007年由比利时软件设计师皮特·亨特金斯(Pieter
Hintjens)及其公司团队开发,旨在提高消息中间件的易用性和性能,也由于此ZeroMQ推出几年间逐渐受到社区关注,在许多大型交易系统得到应用。2016年,身患癌症的亨特金斯在比利时接受安乐死,但他的作品仍然活跃以及被持续维护在十年后的今天,致敬。
ZeroMQ的设计思想十分精巧,虽然从今天视角来看许多艺术已经是非常惯用的设计,这些在英文文档Zguide中展示得详尽且淋漓尽致,详见:https://zguide.zeromq.org,暂未找到近年的中文翻译版本。
本文以Zguide示例为蓝本,完成了C++基本示例的阐述,仅集中于前五章基本设计,更多架构设计哲学参考原文,原文示例仓库来自:https://github.com/imatix/zgu ...