三次B样条曲线拟合算法

1 三次B样条曲线方程

B样条曲线分为近似拟合和插值拟合,所谓近似拟合就是不过特征点,而插值拟合就是通过特征点,但是插值拟合需要经过反算得到控制点再拟合出过特征点的B样条曲线方程。这里会一次介绍两种拟合算法。首先介绍B样条的曲线方程。
B样条曲线的总方程为: P ( t ) = ∑ i = 0 n P i F i , k ( t ) P(t)=\sum_{i=0}^{n} P_{i}F_{i,k}(t) P(t)=i=0nPiFi,k(t) (1)
其中 P i P_i Pi是控制曲线的特征点, F i , k ( u ) F_{i,k}(u) Fi,k(u)则是K阶B样条基函数。
1.1 三次B样条曲线方程中基函数为:
F i , k ( t ) = 1 k ! ∑ m = 0 k − i ( − 1 ) m ( m k + 1 ) ( t + k − m − j ) k F_{i,k}(t)=\frac{1}{k!}\sum_{m=0}^{k-i}(-1)^{m}\binom{m}{k+1}(t+k-m-j)^k Fi,k(t)=k!1m=0ki(1)m(k+1m)(t+kmj)k (2)
其中 ( m k + 1 ) \binom{m}{k+1} (k+1m)表示阶乘,化成看的明白的式子就是:

三次B样条曲线拟合算法_第1张图片
将图片上的基函数代入到方程(1)中,就是:
P ( t ) = P 0 ∗ F 0 , 3 ( t ) + P 1 ∗ F 1 , 3 ( t ) + P 2 ∗ F 2 , 3 ( t ) + P 3 ∗ F 3 , 3 ( t ) P(t)= P_0*F_{0,3}(t)+P_1*F_{1,3}(t)+P_2*F_{2,3}(t)+P_3*F_{3,3}(t) P(t)=P0F0,3(t)+P1F1,3(t)+P2F2,3(t)+P3F3,3(t) (3)
方程(3)就是三次B样条曲线方程。


2019-04-18 更新

有小伙伴提到上式(2)的j是什么意思,其实j就是控制点的索引值。这里我把书上的公式摘抄下来,可能看起来更为清晰。
参考书籍:《计算机图形学 第3版》何援军 第13章
三次B样条曲线计算
F 0 , 3 ( t ) = 1 3 ! ∑ j = 0 3 ( − 1 ) j C 4 j ) ( t + 3 − 0 − j ) 3 F_{0,3}(t)=\frac{1}{3!}\sum_{j=0}^{3}(-1)^{j}C^{j}_{4})(t+3-0-j)^3 F0,3(t)=3!1j=03(1)jC4j)(t+30j)3

= 1 6 [ ( − 1 ) 0 C 4 0 ( t + 3 ) 3 + ( − 1 ) 1 C 4 1 ( t + 2 ) 3 + ( − 1 ) 2 C 4 2 ( t + 1 ) 3 + ( − 1 ) 3 C 4 3 t 3 ] =\frac{1}{6}[(-1)^{0}C^{0}_{4}(t+3)^{3}+(-1)^{1}C^{1}_{4}(t+2)^{3}+(-1)^{2} C^{2}_{4}(t+1)^{3}+(-1)^{3}C^{3}_{4}t^{3}] =61[(1)0C40(t+3)3+(1)1C41(t+2)3+(1)2C42(t+1)3+(1)3C43t3]

= 1 6 ( − t 3 + 3 t 2 − 3 t + 1 ) = 1 6 ( 1 − t ) 3 =\frac{1}{6}(-t^{3}+3t^{2}-3t+1)=\frac{1}{6}(1-t)^{3} =61(t3+3t23t+1)=61(1t)3

F 1 , 3 ( t ) = 1 3 ! ∑ j = 0 2 ( − 1 ) j C 4 j ) ( t + 3 − 1 − j ) 3 F_{1,3}(t)=\frac{1}{3!}\sum_{j=0}^{2}(-1)^{j}C^{j}_{4})(t+3-1-j)^3 F1,3(t)=3!1j=02(1)jC4j)(t+31j)3

= 1 6 [ ( − 1 ) 0 C 4 0 ( t + 2 ) 3 + ( − 1 ) 1 C 4 1 ( t + 1 ) 3 + ( − 1 ) 2 C 4 2 t 3 ] =\frac{1}{6}[(-1)^{0}C^{0}_{4}(t+2)^{3}+(-1)^{1}C^{1}_{4}(t+1)^{3}+(-1)^{2} C^{2}_{4}t^{3}] =61[(1)0C40(t+2)3+(1)1C41(t+1)3+(1)2C42t3]

= 1 6 ( 3 t 3 − 6 t 2 + 4 ) =\frac{1}{6}(3t^{3}-6t^{2}+4) =61(3t36t2+4)

F 2 , 3 ( t ) = 1 3 ! ∑ j = 0 1 ( − 1 ) j C 4 j ) ( t + 3 − 2 − j ) 3 F_{2,3}(t)=\frac{1}{3!}\sum_{j=0}^{1}(-1)^{j}C^{j}_{4})(t+3-2-j)^3 F2,3(t)=3!1j=01(1)jC4j)(t+32j)3

= 1 6 [ ( − 1 ) 0 C 4 0 ( t + 1 ) 3 + ( − 1 ) 1 C 4 1 t 3 =\frac{1}{6}[(-1)^{0}C^{0}_{4}(t+1)^{3}+(-1)^{1}C^{1}_{4}t^{3} =61[(1)0C40(t+1)3+(1)1C41t3

= 1 6 ( − 3 t 3 + 3 t 2 + 3 t + 1 ) =\frac{1}{6}(-3t^{3}+3t^{2}+3t+1) =61(3t3+3t2+3t+1)

F 3 , 3 ( t ) = 1 3 ! ∑ j = 0 0 ( − 1 ) j C 4 j ) ( t + 3 − 3 − j ) 3 F_{3,3}(t)=\frac{1}{3!}\sum_{j=0}^{0}(-1)^{j}C^{j}_{4})(t+3-3-j)^3 F3,3(t)=3!1j=00(1)jC4j)(t+33j)3

= 1 6 [ ( − 1 ) 0 C 4 0 t 3 =\frac{1}{6}[(-1)^{0}C^{0}_{4}t^{3} =61[(1)0C40t3

= 1 6 t 3 =\frac{1}{6}t^{3} =61t3


2 三次B样条曲线近似拟合

近似拟合很简单。不需要求控制点,求得 F i , k ( t ) F_{i,k}(t) Fi,k(t),由上述方程(3),代入 P 0 , P 1 , P 2 , P 3 P_0,P_1,P_2,P_3 P0,P1,P2,P3就可以得到由这四个点近似拟合的一段三次B样条曲线,起始点在 P 0 P_0 P0,终点在 P 1 P_1 P1,对于闭合轮廓,最后一段可以取前两点做辅助,拟合实验结果我最后一块给出。这种近似拟合曲线光滑,但是最大不足就是不过特征点,也就是不过 P i P_i Pi,需要过点需要反求控制点再拟合。

3 三次B样条插值拟合

插值拟合较为复杂。其实也不算是很复杂,找资料过程和理解过程是一个复杂的过程。不过有了前面大神做工作,我们只是借用别人的成果写代码就好了。我给大家看一篇论文,大家可以百度或者去知网搜索,闭合 B 样条曲线控制点的快速求解算法及应用。文章讲解了反求控制点的具体步骤,写的非常详细,基本上贴近代码的那种。大家可以根据这篇论文反求控制点,拟合出来的三次B样条曲线是经过 P i P_i Pi的。代码就不放了,很多,可以根据我给的那篇论文直接编写相应代码,有问题可以私信我,知无不言。
##4 拟合结果
三次B样条曲线拟合算法_第2张图片 原轮廓
三次B样条曲线拟合算法_第3张图片 近似拟合轮廓。可以看到没过黑色特征点,只是近似拟合
三次B样条曲线拟合算法_第4张图片 插值拟。可以看到曲线经过黑色特征点,不过有一些不足之处。

##5 总结
三次B样条曲线拟合轮廓效果还是可以,较之Beizer(可以参考我博客三次Beizer曲线拟合算法),B样条将一些细节描述的很好,很多细节之处都贴近原轮廓,但是有一些不足之处,可以看到对直线拟合效果不是很好。两篇博客都是关于闭合轮廓的拟合,对于非闭合或者只是一段曲线拟合,还有一种曲线是很好的,《数值分析》提到过,叫三次样条插值拟合,拟合效果很好,我做过拟合一元三次方程曲线,拟合效果跟原曲线非常贴近,不过过程中需要用到追赶法,而追赶法需要满足一个条件,对于闭合曲线三次样条插值是不满足这个条件的,所以我没去深研究,大家可以去试一试。谢谢大家!

-------------------------------------------------2018-10-30--------------------------------------------
真的很感谢大家的支持,这一年都比较忙,找实习and找工作,而且这个东西是研一上学期搞的,现在看都毫无印象,对自己说一句:牛逼。我把代码放在网盘了(能运行,但现在没效果,大家可以检查下,之前是OK的),本来想上传到CSDN,好像要C币,而且要审核,太墨迹了。
链接: https://pan.baidu.com/s/1mSQMmvL71gwEAqgiT6O9Gg 提取码: xv5f

你可能感兴趣的:(OpenCV图像处理,C++)