在上一篇博文的最后部分,讲到了文中的双线性插值用于数据缩放的算法存在缺陷,这一篇博文就好好地分析一下。
1. 缺陷存在于缩放后的矩阵中的位置映射回原矩阵进行双线性插值时
1.1. Matlab编程
假如有一个矩阵P,维度是m*n,它要进行缩放的倍率是r,那么缩放以后的矩阵PI的维度是mi*ni,mi是m/r的向下取整数,ni是n/r的向下取整数。那么PI中的第一列的位置一开始是全零的,P(:,1)=0;我将这一列映射到原矩阵P中去,那么在原矩阵中的插值位置是(:, 1/r),这个列号1/r是根据r的大小来看的:如果是放大,r>1,那么插值位置的列号是小于1的,向下取整以后,matlab中矩阵索引号不允许小于1啊,那完了,那向上取整啊,向上取整以后,插值四个已知的点是有了,可是插值的位置还是在0和1之间,那么也把它移过去,这样以后,那么其他的看起来是没问题了,原来列索引在1和2之间的怎么办呢,好的我把所有的都往后移动一位,看起来好像行,那插值位置在最后一列和最后第二列之间的呢,完了,这就是问题所在(2/r是不是也会小于1呢,其他的呢,所以是取决于r的大小的)。那么如果缩小,这个1/r是大于1的,看起来好像可以啊,但是r小一点的话是不是大的有点过了,前面几列的数据都没用到,都挤在后面的列去了,但是后面的隔得也很远啊,也没有超出矩阵维度的问题,那缩小是没问题的。以上是关于列的,行也是一样啊。所以对于matlab这种1开始的矩阵索引,使用上一篇博文中的算法,会造成放大时放大之后的矩阵过度使用第一第二列和第一第二行的数据进行插值,而在缩小时缩小之后的矩阵会忽略前面几行和前面几列的数据。我在上一篇博文的算法中提到,对于超出矩阵维度的情况,可以对超出维度的插值使用离插值处最近的边界进行线性插值,虽然我没有在程序中用这样的方法,但是这样仍然是一种很粗糙的插值方式,超出维度的插值都是相等的了。(以下是针对程序,特殊地,当r是整数时,算法在运算时会超出维度,原因就是放大之后的矩阵在映射回原矩阵时,由于r是整数,行号列号在遍历到最后会正好等于最后一行或最后一列,程序中使用的插值会不适用,这种情况,插值点位置我把它移动到前一个单位去插值,当然也可以用提出的用边界去做线性插值,也应该这么做。)
我用画图软件画一个图来看:
那为什么之前做出来效果还不错呢,图片还蛮清晰的呢,那是因为图像的数据是很大的,边缘的信息质量下降,