薄板样条插值(Thin Plate Spline)

薄板样条插值(Thin Plate Spline)
FesianXu 2020/09/08 at UESTC

前言

本文是笔者阅读[1]过程中,遇到了关于Thin Plate Spline[5]相关的知识,因而查找若干资料学习后得到的一些笔记,本文主要参考[2,3,4],希望对大家有所帮助。 如有谬误,请联系指出,转载请联系作者并注明出处

∇ \nabla 联系方式:

e-mail: FesianXu@gmail.com

QQ: 973926198

github: https://github.com/FesianXu

知乎专栏: 计算机视觉/计算机图形理论与应用

微信公众号
qrcode


薄板样条插值

薄板样条插值(Thin Plate Spline,TPS)是插值方法的一种,是常用的2D插值方法。假如给定两张图片中一些相互对应的控制点,如何将其中一个图片进行特定的形变,使得其控制点可以与另一张图片的控制点重合,如Fig 1.1所示。当然,提供插值的方法也特别的多,TPS是其中一种技术,其有着一个基本假设

如果用一个薄钢板(只是一个比喻)的形变来模拟这种2D形变,在确保所有控制点能够尽可能匹配的情况下,怎么样才能使得钢板的弯曲量最小。

几乎所有的生物有关的形变都是可以用TPS来近似,因此TPS也经常被用于脸部关键点形变等相关的应用[1]。

tps

Fig 1.1 该图演示了TPS的基本任务,(a)图的p点表示的是移动之前的点,而q点表示的是移动之后的点,若干控制点产生了这种移动之后,势必整个平面发生了扭曲,其结果如(b)所示,TPS的目的就是拟合得到每个曲面上的点的变化。

为了描述整个插值过程,按照我们刚才所说的,需要定义两个项,一个是拟合项 E Φ \mathcal{E}_{\Phi} EΦ,测量将源点变形后距离目标点的大小;第二个是扭曲项 E d \mathcal{E}_{d} Ed,测量曲面的扭曲大小。那么有总的损失函数:
E = E Φ + λ E d (1.1) \mathcal{E} = \mathcal{E}_{\Phi}+\lambda \mathcal{E}_{d} \tag{1.1} E=EΦ+λEd(1.1)
其中的 λ \lambda λ为权值系数,控制允许非刚体形变发生的程度,不同的 λ \lambda λ对于整个拟合效果的影响如Fig 1.2所示。

diff_lambda

Fig 1.2 不同的权重系数对于拟合效果的影响,越大的权重变形就越接近仿射变换。

其中有:
E Φ = ∑ i = 1 N ∣ ∣ Φ ( p i ) − q i ∣ ∣ 2 (1.2) \mathcal{E}_{\Phi} = \sum_{i=1}^{N}||\Phi(p_i)-q_i||^2 \tag{1.2} EΦ=i=1NΦ(pi)qi2(1.2)

E d = ∫ ∫ R 2 ( ( ∂ 2 Φ ∂ x 2 ) 2 + 2 ( ∂ 2 Φ ∂ x ∂ y ) 2 + ( ∂ 2 Φ ∂ y 2 ) 2 ) 2 d x d y (1.3) \mathcal{E}_d = \int \int_{\mathbb{R}^2} \bigg( \bigg( \dfrac{\partial^2\Phi}{\partial \mathrm{x}^2} \bigg)^2 + 2 \bigg( \dfrac{\partial^2\Phi}{\partial \mathrm{x} \partial \mathrm{y}} \bigg)^2 + \bigg( \dfrac{\partial^2\Phi}{\partial \mathrm{y}^2} \bigg)^2 \bigg)^2 \mathrm{dx}\mathrm{dy} \tag{1.3} Ed=R2((x22Φ)2+2(xy2Φ)2+(y22Φ)2)2dxdy(1.3)

其中的 N N N为控制点的数量,式子(1.2)很容易理解,是源目标经过形变函数 Φ \Phi Φ之后和目标之间的距离;而式子(1.3)是曲面扭曲的能量函数,由文献[6]中给出,最小化式子(1.1)的结果,可以推导出形变函数的唯一闭式解结果为:
Φ ( p ) = M ⋅ p + m 0 + ∑ i = 1 N ω i U ( ∣ ∣ p − p i ∣ ∣ ) (1.4) \Phi(p) = \mathbf{M} \cdot p + m_0+\sum_{i=1}^{N} \omega_i U(||p-p_i||) \tag{1.4} Φ(p)=Mp+m0+i=1NωiU(ppi)(1.4)
其中 p p p为曲面上的任意一个点,有 p = ( x , y ) T p = (x,y)^{\mathrm{T}} p=(x,y)T p i p_i pi是对应域的控制点,而 M = ( m 1 , m 2 ) \mathbf{M} = (m_1,m_2) M=(m1,m2),而这里的 U ( ⋅ ) U(\cdot) U()为径向基函数,表示某个曲面上的点的变形会受到所有控制点变形的影响(当然,不同控制点的影响程度不一样),有
U ( x ) = r 2 log ⁡ r (1.5) U(x) = r^2\log{r} \tag{1.5} U(x)=r2logr(1.5)
ω i \omega_i ωi表示对不同径向基的加权。如Fig 1.3所示,如果我们假设每个控制点都对应一个高度,也就是 ( x i , y i ) → v i (x_i,y_i)\rightarrow v_i (xi,yi)vi,也就是说控制点是三维空间坐标系中的自变量,而其高度是因变量,那么我们可以再继续分析式子(1.4)中的第一项和第二项。

我们发现第一项其实是尝试用一个平面 y = M ⋅ p + m 0 y = \mathbf{M} \cdot p+m_0 y=Mp+m0去拟合所有的目标控制点,当然这个拟合肯定不够好,因此用第二项尝试在该平面的基础上去弯曲(当然是尽可能小的弯曲),从而达到更好的拟合效果,如Fig 1.3所示。此时有未知参数 M ∈ R 2 , m 0 ∈ R \mathbf{M} \in \mathbb{R}^2, m_0 \in \mathbb{R} MR2,m0R,和 ω i , i ∈ [ 1 , N ] \omega_i, i \in [1,N] ωi,i[1,N],因此一共有 1 + 2 + N 1+2+N 1+2+N个参数,其中 D = 2 D = 2 D=2是维度, N N N是控制点数目。

thinplates

Fig 1.3 最小程度地扭曲平面,使得该曲面可以符合所有的控制点,而扭曲程度最小。

我们为了求解形式一般化,用以下矩阵代表之前谈到的数值,有:
P = [ 1 x 1 y 1 1 x 2 y 2 ⋮ ⋮ ⋮ 1 x n y n ] (1.6) \mathbf{P} = \left[ \begin{matrix} 1 & x_1 & y_1 \\ 1 & x_2 & y_2 \\ \vdots & \vdots & \vdots \\ 1 & x_n & y_n \end{matrix} \right] \tag{1.6} P=111x1x2xny1y2yn(1.6)
其中每一行代表一个控制点坐标,该矩阵称之为控制点矩阵。
Y = [ v 1 v 2 ⋮ v n 0 0 0 ] (1.7) \mathbf{Y} = \left[ \begin{matrix} v_1 \\ v_2 \\ \vdots \\ v_n \\ 0 \\ 0 \\ 0 \\ \end{matrix} \right] \tag{1.7} Y=v1v2vn000(1.7)
该矩阵称之为高度矩阵,后面三个0是为了形式统一填充的。

K = [ U ( r 11 ) U ( r 12 ) ⋯ U ( r 21 ) U ( r 22 ) ⋯ ⋯ ⋯ U ( r N N ) ] (1.8) \mathbf{K} = \left[ \begin{matrix} U(r_{11}) & U(r_{12}) & \cdots \\ U(r_{21}) & U(r_{22}) & \cdots \\ \cdots & \cdots & U(r_{NN}) \end{matrix} \right] \tag{1.8} K=U(r11)U(r21)U(r12)U(r22)U(rNN)(1.8)
其中 r i j = ∣ ∣ p i − p j ∣ ∣ r_{ij} = ||p_{i}-p_{j}|| rij=pipj表示两个控制点之间的距离。令矩阵 L \mathbf{L} L为:
L = [ K P P T 0 ] ∈ R ( N + 3 ) × ( N + 3 ) (1.9) \mathbf{L} = \left[ \begin{matrix} \mathbf{K} & \mathbf{P} \\ \mathbf{P}^{\mathrm{T}} & \mathbf{0} \end{matrix} \right] \in \mathbb{R}^{(N+3) \times (N+3)} \tag{1.9} L=[KPTP0]R(N+3)×(N+3)(1.9)
那么由式子(1.4)和 Φ ( p i ) = v i \Phi(p_i)=v_i Φ(pi)=vi,有:
Y = L ( Ω ∣ m 0 , m 1 , m 2 ) T (1.10) \mathbf{Y} = \mathbf{L} (\Omega|m_0,m_1,m_2)^{\mathrm{T}} \tag{1.10} Y=L(Ωm0,m1,m2)T(1.10)
其中 Ω = ( ω 1 , ⋯   , ω N ) \Omega = (\omega_1,\cdots,\omega_N) Ω=(ω1,,ωN)。其中的后三行引入了一组对参数的约束(虽然我并不知道这组约束的含义,有了解的朋友请在评论区赐教,谢谢):
∑ i = 1 N ω i = 0 ∑ i = 1 N x i ω i = 0 ∑ i = 1 N y i ω i = 0 (1.11) \begin{aligned} \sum_{i=1}^N \omega_i &= 0 \\ \sum_{i=1}^N x_i\omega_i &= 0 \\ \sum_{i=1}^N y_i\omega_i &= 0 \end{aligned} \tag{1.11} i=1Nωii=1Nxiωii=1Nyiωi=0=0=0(1.11)
那么从式子(1.10)我们有:
( Ω ∣ m 0 , m 1 , m 2 ) T = L − 1 Y (1.12) (\Omega|m_0,m_1,m_2)^{\mathrm{T}} = \mathbf{L}^{-1}\mathbf{Y} \tag{1.12} (Ωm0,m1,m2)T=L1Y(1.12)
当然也可以通过解线性方程组(1.10)得到参数组 ( Ω ∣ m 0 , m 1 , m 2 ) T (\Omega|m_0,m_1,m_2)^{\mathrm{T}} (Ωm0,m1,m2)T,一旦这个参数组计算得到,那么我们的插值函数 Φ ( p ) \Phi(p) Φ(p)也就已知了,只要给定平面上任意一个点,就能通过插值函数将其插值到目标平面上。

变形(deformation)

这里介绍TPS的一个主要应用,对图片的控制点进行偏移,以达到通过控制点对图像进行特定形变的目的。如Fig 2.1所示,通过拉拽嘴角的控制点(即是蓝色点),使得周围的像素,比如 A A A点移动到了 A ′ A^{\prime} A点,此时存在位移 ( Δ x , Δ y ) (\Delta x, \Delta y) (Δx,Δy),此时我们需要插值这个位移。 当然,对应控制点之间的移动偏移是可以知道的,记为 Δ S = { ( Δ x 1 , Δ y 1 ) , ⋯   , ( Δ x N , Δ y N ) } \Delta \mathbf{S} = \{(\Delta x_1, \Delta y_1),\cdots,(\Delta x_N, \Delta y_N)\} ΔS={(Δx1,Δy1),,(ΔxN,ΔyN)},我们要根据已知的控制点偏移去插值图片上其他任意像素点的偏移。

不妨我们把这两个位移的分量隔离开来,不考虑两个维度之间的相关性,那么可以将第一章提到的“高度” v i v_i vi在这里理解成每一个位移的分量,那么我们有两个插值函数需要预测,即是:
Δ x ( p ) = Φ ( p ) Δ x Δ y ( p ) = Φ ( p ) Δ y (2.1) \begin{aligned} \Delta x(p) &= \Phi(p)_{\Delta x} \\ \Delta y(p) &= \Phi(p)_{\Delta y} \end{aligned} \tag{2.1} Δx(p)Δy(p)=Φ(p)Δx=Φ(p)Δy(2.1)

deformation_face

Fig 2.1 通过拉拽嘴角和眼角的控制点,可以实现图像的内容形变。

假如只是选定6个控制点,分别是图片的四个角落,右眼和右侧嘴角,如Fig 2.2所示,其中红色点表示移动之前的控制点,绿色点表示移动后的控制点,我们发现只是移动了右边眼睛和右边嘴角。那么计算出来的插值函数 Φ \Phi Φ为:
Φ = [ Φ ( p ) Δ x Φ ( p ) Δ y ] (2.2) \Phi = \left[ \begin{matrix} \Phi(p)_{\Delta x} \\ \Phi(p)_{\Delta y} \end{matrix} \right] \tag{2.2} Φ=[Φ(p)ΔxΦ(p)Δy](2.2)
其图像如Fig 2.3所示。我们发现在四个角落,因为不存在控制点的位移,因此 Δ x , Δ y \Delta x, \Delta y Δx,Δy的平面没有高度变化,而嘴角向上移动,因此对应嘴角的控制点的曲面上的 Δ y \Delta y Δy有着较高的高度,而对应的 Δ x \Delta x Δx则没有太大的高度变化。相反的,右眼部分则是 Δ x \Delta x Δx有着较为明显的高度变化,而 Δ y \Delta y Δy没有。

herve-smile-points

Fig 2.2 红色点表示移动之前的控制点,绿色点表示移动后的控制点,我们发现只是移动了右边眼睛和右边嘴角。

只要得到了这个 Δ x , Δ y \Delta x, \Delta y Δx,Δy方向的插值函数,给定任意一组控制点的变化,都可以对其他非控制点的像素位置进行插值。

dxdy

Fig 2.3 △x和△y的插值函数图像,其中的红点表示控制点。

Update 20201028
更新一个来自知乎朋友的问题,链接在:https://zhuanlan.zhihu.com/p/227857813

ID:qing3
问题:请问为什么公式1.4的结果是标量呀,而公式1.2中把公式1.4的结果当做向量来计算的

首先我们要知道,以二维图片的变形为例子,该TPS拟合函数 Φ ( p ) \Phi(\mathbf{p}) Φ(p),是给定一个图片中的二维坐标 p = ( x , y ) T \mathbf{p} = (x,y)^{\mathrm{T}} p=(x,y)T,去拟合该处的灰度值(当然也可以是RGB通道,只不过如果是RGB通道的话需要三个不同的拟合函数),因此该拟合函数的输出值是标量,回到式子(1.2),我发现该式子写得有点小问题,容易造成误解,我后面改成式子(a1),其中的 v ( ⋅ ) v(\cdot) v()表示对给定的坐标取灰度值,因此也是一个标量函数。这样子就不会有误解了。建议可以看看Fig 1.3会有更直观的感受,其预测值可以看成是高度,因此才会用“薄板变形”去形容这个过程,是很形象的。

E Φ = ∑ i = 1 N ∣ ∣ Φ ( p i ) − v ( q i ) ∣ ∣ 2 (a1) \mathcal{E}_{\Phi} = \sum_{i=1}^{N}||\Phi(p_i)-v(q_i)||^2 \tag{a1} EΦ=i=1NΦ(pi)v(qi)2(a1)


Reference

[1]. Siarohin, A., Lathuilière, S., Tulyakov, S., Ricci, E., & Sebe, N. (2019). First order motion model for image animation. In Advances in Neural Information Processing Systems (pp. 7137-7147).

[2]. http://profs.etsmtl.ca/hlombaert/thinplates/

[3]. https://www.jianshu.com/p/2cc189dfbcc5#fn3

[4]. https://www.cse.wustl.edu/~taoju/cse554/lectures/lect07_Deformation2.pdf

[5]. Bookstein, F. L. (1989). Principal warps: Thin-plate splines and the decomposition of deformations. IEEE Transactions on pattern analysis and machine intelligence, 11(6), 567-585.

[6]. Kent, J. T. and Mardia, K. V. (1994a). The link between kriging and thin-plate splines. In: Probability, Statistics and Optimization: a Tribute to Peter Whittle (ed. F. P. Kelly), pp 325–339. John Wiley & Sons, Ltd, Chichester. page 282, 287, 311

<think>好的,用户需要寻找在Matlab中实现薄板样条(TPS)插值的代码示例。首先,我需要确认薄板样条插值的基本原理和数学表达式,这样才能正确指导代码实现。TPS通常用于二维空间中的插值问题,其核心是求解一个线性方程组,结合仿射变换和径向基函数。 接下来,我应该回忆Matlab中是否有内置函数可以直接实现TPS。记得Matlab的Curve Fitting Toolbox中有`tpaps`函数,可以用于薄板样条插值。用户可能需要安装这个工具箱,需要检查是否可用。此外,如果用户没有这个工具箱,可能需要手动实现TPS的数学公式。 然后,我需要考虑用户提供的引用内容。引用[1]提到了使用插值薄板样条,引用[2]指出插值等同于薄板样条,引用[3]提到一个没有插值的最小示例。这说明用户可能希望有一个完整的插值示例,而不仅仅是基础代码。因此,示例代码需要包含数据生成、模型拟合和结果可视化步骤。 接下来,构建代码框架。首先使用`tpaps`函数,需要生成一些示例数据点,比如随机点或者网格点。然后调用`tpaps`进行拟合,平滑参数可能需要调整。最后,通过`fnplt`绘制结果,或者进行预测点的插值。需要确保代码的每一步都有注释,方便用户理解。 另外,用户可能对参数设置不太清楚,比如平滑参数λ的作用。需要解释λ=0时为精确插值,λ越大平滑效果越明显。同时,可能存在的错误处理,比如数据维度是否正确,是否需要归一化等注意事项也要提及。 考虑到用户可能没有Curve Fitting Toolbox,手动实现TPS也是一个选项。需要构造系数矩阵,包括径向基函数部分和仿射变换部分,然后解线性方程组。这部分数学公式较为复杂,可能需要用Matlab的矩阵运算来实现。例如,计算点之间的距离矩阵,构造K矩阵,然后组装大矩阵求解权重和仿射系数。 在手动实现的代码中,需要注意数值稳定性,比如矩阵求逆时可能出现的奇异问题。可能需要使用伪逆或者其他方法。这部分代码可能较为复杂,用户可能需要更多的解释和注释。 此外,用户可能需要比较不同实现方法的优缺点,比如内置函数的高效性和手动实现的灵活性。引用文献中的信息可能需要关联到代码中的具体步骤,例如引用[1]提到的向量值插值,可能在Matlab中如何处理多维输出。 最后,生成相关问题,需要考虑用户可能进一步的问题,比如如何选择平滑参数,处理三维数据,与其他插值方法的比较,以及实际应用案例等。确保问题覆盖了理论、实现和应用的不同方面,帮助用户深入理解TPS在Matlab中的使用。</think>以下是在Matlab中实现薄板样条Thin Plate Spline,TPS)插值的代码示例和说明: ### 薄板样条插值实现步骤 1. **定义控制点**:输入二维/三维控制点坐标和对应的函数值 2. **构造矩阵方程**:根据TPS的泛函方程建立线性方程组 3. **求解权重系数**:通过矩阵分解计算样条参数 4. **生成插值曲面**:使用计算得到的参数进行空间插值 ### 使用Curve Fitting Toolbox实现 ```matlab % 生成示例数据(10个随机控制点) x = rand(10,1)*4-2; y = rand(10,1)*4-2; z = peaks(x,y); % 使用Matlab内置peaks函数生成对应值 % 薄板样条插值(精确插值) lambda = 0; % 平滑参数,0表示严格插值 st = tpaps([x,y]', z', lambda); % 结果可视化 fnplt(st), hold on plot3(x,y,z,'ro','MarkerFaceColor','r') title('薄板样条插值曲面'), axis tight ``` 注:`tpaps`函数需要Curve Fitting Toolbox支持,λ参数控制插值光滑度(0为精确插值)[^1] ### 手动实现TPS核心算法 ```matlab function [z_new] = TPS_interp(x,y,z,x_new,y_new) % 输入参数: % (x,y,z): 控制点坐标及值 % (x_new,y_new): 待插值点坐标 n = length(x); K = zeros(n,n); for i = 1:n for j = 1:n r = norm([x(i)-x(j), y(i)-y(j)]); K(i,j) = r^2 * log(r + eps); % 径向基函数 end end P = [ones(n,1), x, y]; A = [K P; P' zeros(3,3)]; b = [z; zeros(3,1)]; w = A \ b; % 求解系数 % 计算插值点 m = length(x_new); z_new = zeros(m,1); for k = 1:m sum = 0; for i = 1:n r = norm([x_new(k)-x(i), y_new(k)-y(i)]); sum = sum + w(i) * r^2 * log(r + eps); end z_new(k) = sum + w(n+1) + w(n+2)*x_new(k) + w(n+3)*y_new(k); end end ``` 该实现基于TPS的数学定义[^2],适用于理解算法原理,但需注意数值稳定性问题。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FesianXu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值