目录
移动最小二乘法图像变形的论文链接见:https://www.cs.rice.edu/~jwarren/research/mls.pdf,目前CSDN上有一些相关博客,如https://blog.csdn.net/tuntunmmd/article/details/106211053,但基本都止于将英文论文核心部分简单翻译一下而已,这里我将尝试给出其中部分跳跃性较大部分的公式推导,并结合MatLab源码进行完整图像变形流程的讲解。
下面先给出程序链接及程序使用演示GIF:
链接:https://pan.baidu.com/s/1ieeI1jU4OO7eEHPIkknUDw 提取码:k8dc
基本原理
基于移动最小二乘的图像变形,其原理简单来说就是通过一些源控制点和目标控制点(源控制点对应的变形后位置点)控制变形,对于每一个待求变形后位置的点而言,首先根据预设的形变类型(如仿射变换、相似变换、刚性变换)通过求解一个最小二乘优化目标函数估计一个局部的坐标变换矩阵,然后将该坐标变换矩阵应用于当前点即可计算出该点变形后的位置。求得每一个像素点对应的变形后坐标后(正向映射),就不难反推出变形后图像中每个像素点对应的源像素点位置并插值计算出相应的像素值,得到变形后的图像。由于对于每一个待求变形后位置的点,都要建立一个优化目标函数求解一个局部性坐标变换矩阵,因此该方法称为“移动最小二乘法”。在优化目标函数中,对于当前待求变形后位置点而言,与其距离越近的源控制点具有越高的权重,对应的期望变形后位置与预设目标控制点的位置误差越小,且权重衰减迅速,对于距离当前点较远的控制点,其权重近似为0,这体现了所期望的形变模型的局部性。
移动最小二乘变形也可以用于轮廓变形,求得一系列轮廓点对应的变形后的轮廓点后将它们连接起来便获得了变形后的轮廓。本人据此开发了一款基于参考轮廓与轮廓变形的工业品图像区域轮廓提取算法,该方法具有很好的鲁棒性,能够有效处理因图像亮暗不均、噪声干扰严重、图像局部扭曲变形、轮廓局部断裂、轮廓两侧对比度过低、轮廓两侧亮度关系反转等问题引起的轮廓提取失败问题,同时能保证所提取轮廓的连续性与平滑性,避免了一般工业品图像区域边界轮廓提取算法的断裂连接后处理工作,并且易于利用先验知识和现有技术对算法进行改造以适应实际情况获得更好的性能。此外,算法还具有原理简单、精度高、效率高的优点。目前该算法正在专利申请中,尚不能对大众公开,请各位读者见谅。
公式推导
接下来开始公式推导。为了节省篇幅和省去不必要的麻烦,我将不再从头开始讲解,而直接就跳跃性大的公式进行公式推导。请读者结合原论文和前述引用的博客进行理解。
由论文中的公式推导知,一般化的仿射变换对应的优化目标函数:
到了相似变换,优化目标函数变成了:
这一步论文中没有给出公式推导,下面我来补充一下。
首先,对于相似变换,其投影矩阵为:
其中,。
令,
,由于:
于是,
对上式取转置,则有:
(4)式由此化为:
论文中给出最优解的变换矩阵为
事实上,这是作者笔误写错了,其中的应该改为
,这一点不难证明。这实际上就是一个求加权最小二乘解的问题,
优化目标为:
求导得:
最优解为
这里,
。
设,则:
而
故而有:
由论文中(3)式,有:
将前面表达式代入,有:
记和
,二者分别为1x2的行向量和2x1的列向量,我们聚焦于分析和式中的一个分项,则:
其中倒数第二步用到了。因公式输入不便,其中的小细节不再给出证明,读者可以方便地自行推导出来。由此不难得出论文中
的表达式。网格变形公式的推导与其类似,因过程过于繁琐,这里就不再给出了。读者只需理解论文中对
归一化的妙用即可。
MLS用于图像变形及本人对源码的改动
将MLS用于图像变形时,我们将p映射到q,将网格v映射为变形的网格sfv。在计算目标图像中各像素点的像素值时,我们首先需要找到该像素点在原图像中的位置。这一步是通过插值得到的。如果我们知道目标图像中一些网格顶点在原图像中的位置,那么我们就可以通过插值得到目标图像中任意一点在原图像中的对应位置。为此,我们首先需要在目标图像中寻找一些对应位置已知的网格点。因此,我们需要将变形的网格sfv约化为棋盘格。源码中简单地用v替代sfv,即认为变形前后网格顶点位置未变,这样在变形剧烈时可能误差过大。为此,我做了个简单的改进,就是对变形网格sfv分别求x轴和y轴投影作为约化后网格点的x坐标(阵列)和y坐标(阵列),由此构建约化的棋盘格。在求出棋盘格格点变形前后的偏移量后,目标图像中任一像素点变形前后的偏移量也就可以插值得到,从而获得该像素点的像素值。
本人改动的核心部分代码为:
% Computing the displacements:
dxy = v-sfv;
% dxT = interp2(X,Y,reshape(dxy(1,:),size(X)),TX,TY);
% dyT = interp2(X,Y,reshape(dxy(2,:),size(X)),TX,TY);
RX=reshape(sfv(1,:),size(X));
RY=reshape(sfv(2,:),size(Y));
mX=mean(RX,1);
mY=mean(RY,2);
RX=repmat(mX,size(X,1),1);
RY=repmat(mY,1,size(Y,2));
dxT = interp2(RX,RY,reshape(dxy(1,:),size(X)),TX,TY);
dyT = interp2(RX,RY,reshape(dxy(2,:),size(X)),TX,TY);
其中,注释掉的两行为源代码,后面的部分为我个人修正后的代码。
我本欲为大家做一下公式内涵的解读,但奈何这会儿已经太晚了,而我还没吃晚饭。本次讲解只好先讲到这里,以后有机会再予以补充。有不明白的地方读者可在评论区留言,我在空闲的时候会尽力给以解答。