如何在转换后获得插值点
Posted
技术标签:
【中文标题】如何在转换后获得插值点【英文标题】:How to get interpolation points after a transformation 【发布时间】:2022-01-10 07:33:09 【问题描述】:我有一个程序可以对图像进行缩放和旋转,算法的工作原理如下:
(pseudocode)
for (x, y) in dest
ox, oy = transform(x, y)
dest[x,y] = src[ox, oy]
我决定实现双线性插值以获得更好的结果,但是我不知道如何得到变换后x,y周围的四个已知点。
我尝试过这样做:
(pseudocode)
for (x, y) in dest
ox, oy = transform(x, y)
dest[x,y] = (src[ox, oy] + src[ox + 1, oy] +
src[ox, oy + 1] + src[ox + 1, oy + 1])/4
这给出了插值的外观,但像素仍然非常清晰。用 16 个像素做同样的事情(尝试实现双三次)结果更糟,图像具有清晰的像素,同时非常模糊
最终结果是 512x512(dest),但看起来它在仍然 32x32(src)时被插入,然后使用最近邻进行缩放。我做错了什么?
【问题讨论】:
插值:映射点。这将是一些浮点数,而不是整数。上下四舍五入每个坐标。现在你有了源中相邻四个像素的整数坐标。现在你需要取出你切掉的小数部分,并在双线性计算中使用它们。 这会导致我尝试做同样的事情,向上和向下舍入会使点相隔一个像素。像这样计算会产生图像上显示的问题 【参考方案1】:看起来它在仍为 32x32 (src) 时已被插入,然后使用最近的邻居进行缩放。
我认为这正是正在发生的事情,我试图重用最近邻函数,但使用插值。原来,通过这样做,我在 32x32 空间内进行插值
正确的算法应该是这样的:
(pseudocode)
for (ox, oy) in src
x, y = transform_inv(ox, oy)
dest[x, y] = src[ox, oy]
known += (x, y)
for (x, y) in dest
if (x, y) not in known
dest[x, y] = interpolate(known, x, y)
编辑: 较旧的算法有效,并且比填补空白更有效。我需要考虑的是 512x512 空间上每个像素之间的距离作为平均函数的权重
(pseudocode)
for (x, y) in dest
ox, oy = transform(x, y)
p1 = src[ox, oy]
p2 = src[ox + 1, oy]
p3 = src[ox, oy + 1]
p4 = src[ox + 1, oy + 1]
d1 = distance(transform_inv(ox, oy), (x, y))
d2 = distance(transform_inv(ox + 1, oy), (x, y))
d3 = distance(transform_inv(ox, oy + 1), (x, y))
d4 = distance(transform_inv(ox + 1, oy + 1), (x, y))
dt = d1 + d2 + d3 + d4
dest[x,y] = ((p1 * d1) + (p2 * d2) + (p3 * d3) + (p4 * d4))/dt
编辑2: 在较低的分辨率上看起来很奇怪(编辑之前的图像我不小心用 128x128 而不是 32x32 测试),可能还有一些需要改进的地方
【讨论】:
抱歉,该代码不正确。您不能遍历源像素并将它们映射到目标位置。这可能会导致输出中出现任意大的间隙。你注意到了,但“修复”是不够的(!),甚至不需要,如果你做得对的话。 -- 通常的方法是反转正向变换,遍历目标像素,查找每个像素的源位置。 大的空白将被插值步骤填补,这将找到known
数据结构上最近的四个点。迭代目标到源是我这样做的方式,但没有工作以上是关于如何在转换后获得插值点的主要内容,如果未能解决你的问题,请参考以下文章
图像插值基于matlab稀疏拉普拉斯滤波器图像插值含Matlab源码 2055期