曲线曲面拟合
·
一、理论
实际工程中基本都是像素点的离散采样,那么如果一个变化趋势符合二次曲线或二次曲面的时候,就可以通过拟合的方式获得曲线或曲面的极值位置。
二、三点抛物线拟合
假如我们有一个等距采样的序列,在峰值附近取3个连续点:
1.
x0=-d,x1=0,x2=+d,其中d就是采样间隔(通常d=1像素);
对应的函数值y0,y1,y2,且y1是三者最大值(峰值)或最小值;
用二次函数拟合三点:f(x)=axx+bx+c
2.
将三点代入公式,
add - b d +c =y0
c=y1
add+bd+c=y2
3.
二次函数极值点x= -b / (2 a)
x=(y0-y2)/(y0-y1*y1+y2)*d/2
因为d=1(像素),
所以实际的极值点位置为X(像素级)+x(小数),也就是亚像素的位置
说明:这三点已经以峰值点为中心对称选取(即 𝑥1是峰值点);实际使用时,应先找到离散最大值点,然后取该点及其左右邻居;如果分母 为零(即三点共线或无法拟合),说明峰值尖锐或噪声影响,此时可回退到直接取中心点。
三、代码
/// <summary>
/// 三点抛物线拟合,采样间隔为整数像素
/// </summary>
/// <param name="y0">左 灰度值</param>
/// <param name="y1">中</param>
/// <param name="y2">右</param>
/// <param name="dx">采样间距</param>
/// <returns>y1对应的x1的偏移量 即x1+返回值==极值点对应的x值</returns>
float parabolicPeak(float y0, float y1, float y2, float dx = 1.0f) {
float a = (y0 - 2 * y1 + y2) / 2;
float b = (y0 - y2) / 2;
if (a == 0) return 0;
return b / (2 * a) * dx;
}
四、说明
抛物线拟合适合于离散点求极值,针对数学计算
也适合于求亚像素坐标点,针对图像处理(可分别进行x和y方向的插值,计算得到point2f点)
五、如果有多点拟合二次曲线,例如通过最小二乘法求解系数,可通过solve函数进行求解
获取源码请私信,可指导配置技术交流
更多推荐
所有评论(0)