当使用各种不同的方法缩小比例时,图像梯度变得不准确
Image gradients become inaccurate when downscaling using a variety of different methods
我们有一个用 Python 编写的相当复杂的图像处理脚本,它使用 PIL 和 numpy。对于其中一个步骤,我们有一个非常敏感的多通道梯度,它是一个查找 table。创建后,它会被保存为多个不同的较小分辨率。然而,当这种情况发生时,从左到右具有梯度 运行 的绿色通道突然变得不清晰了。它应该每 50 个像素左右丢失 255 个值中的 1 个。相反,它开始每 100 个像素下降 2 个值。这导致了巨大的问题,我不明白为什么 PIL 这样做。但是,我确实在地图的其他部分看到了 1 的跳跃,所以我认为它并不简单,因为它缺少一点精度。我还在另一个频道上注意到,整个地图似乎都移动了 1 个值。即使使用 "Nearest" 过滤器,整个事情在缩放后似乎也不准确。
对于全尺寸图像,我们使用以下命令从 numpy 数组创建它:
image = Image.fromarray(imageIn.astype(np.uint8))
然后我们缩小它:
new_image = image.resize(new_size, scaleFilter)
比例总是最大的一半,我已经尝试了所有可用的比例选项。
然后我们将其保存为 PNG,如下所示:
new_image.save(file_name, 'PNG')
我们在步骤 1 之后使用相同的保存命令直接保存了两个大的,没问题。规模之后,我们在绿色通道上有问题。任何帮助都会很棒!
编辑:
现在看来这很可能是 SciPy 中的一个问题。以下仍然会导致问题:
new_array = misc.imresize(imageIn, (x_size, y_size, 4), interp='nearest')
misc.imsave(file_name,new_array)
我不明白我是怎么得到最近的扭曲的。我将此数组分配为 float64,但它必须涉及代码中的舍入问题
编辑#2:
我更进一步并尝试 OSX 内置程序 sips 下载它并得到相同的失真!然后我用 Adobe After Effects 试了一下,效果很好。然后我安装了 imagemagick,现在可以正常工作了。我仍然会将赏金奖励给任何能够解释为什么在所有这些方法中发生这种情况的人。
编辑#3
根据要求,这是缩放和未缩放的精灵贴图的一部分。在创建这些过程中,我发现 OSX 的内置 "Preview" 应用程序在缩小时也会导致缩放问题,所以我实际上不得不使用 photoshop 来获取原始剪辑。
原文:
缩放失真。尝试沿水平轴观察绿色通道
请注意,这些剪裁并不是完全相同的像素,而是从形状中看到的相同区域剪裁的
编辑 #4
我现在已经尝试在应用程序中通过 OpenGL 进行这种缩放,我发现它也发生在那里!这与使用固定位数进行双线性插值的一些基本问题有关?
使用 skimage 缩放 50% 时,以下代码似乎可以正确执行操作:
import numpy
import skimage
import skimage.io
img = skimage.io.imread('uY173.png')
import skimage.transform
img50_order0 = skimage.img_as_ubyte( skimage.transform.rescale(img, 0.5, order=0, clip=True) )
img50_order1 = skimage.img_as_ubyte( skimage.transform.rescale(img, 0.5, order=1, clip=True) )
img50_lm = numpy.rint( skimage.transform.downscale_local_mean(img, (2,2,1), clip=True) )
import scipy.ndimage.interpolation
img50_nd = scipy.ndimage.interpolation.zoom(img, (0.5, 0.5, 1))
# plot section of green channel along horizontal axis
plot(img50_order0[50, :, 1])
plot(img50_order1[50, :, 1])
plot(img50_lm[50, :, 1])
plot(img50_nd[50, :, 1])
这(据我所知)并不依赖于引擎盖下的 PIL。源图像被读取为 uint8,在每个图像中以略微不同的方式进行处理和舍入,从而产生 uint8 输出。但是,所有这些之间的差异永远不会超过 1,并且步长永远不会超过 2。
我们有一个用 Python 编写的相当复杂的图像处理脚本,它使用 PIL 和 numpy。对于其中一个步骤,我们有一个非常敏感的多通道梯度,它是一个查找 table。创建后,它会被保存为多个不同的较小分辨率。然而,当这种情况发生时,从左到右具有梯度 运行 的绿色通道突然变得不清晰了。它应该每 50 个像素左右丢失 255 个值中的 1 个。相反,它开始每 100 个像素下降 2 个值。这导致了巨大的问题,我不明白为什么 PIL 这样做。但是,我确实在地图的其他部分看到了 1 的跳跃,所以我认为它并不简单,因为它缺少一点精度。我还在另一个频道上注意到,整个地图似乎都移动了 1 个值。即使使用 "Nearest" 过滤器,整个事情在缩放后似乎也不准确。
对于全尺寸图像,我们使用以下命令从 numpy 数组创建它:
image = Image.fromarray(imageIn.astype(np.uint8))
然后我们缩小它:
new_image = image.resize(new_size, scaleFilter)
比例总是最大的一半,我已经尝试了所有可用的比例选项。
然后我们将其保存为 PNG,如下所示:
new_image.save(file_name, 'PNG')
我们在步骤 1 之后使用相同的保存命令直接保存了两个大的,没问题。规模之后,我们在绿色通道上有问题。任何帮助都会很棒!
编辑:
现在看来这很可能是 SciPy 中的一个问题。以下仍然会导致问题:
new_array = misc.imresize(imageIn, (x_size, y_size, 4), interp='nearest')
misc.imsave(file_name,new_array)
我不明白我是怎么得到最近的扭曲的。我将此数组分配为 float64,但它必须涉及代码中的舍入问题
编辑#2:
我更进一步并尝试 OSX 内置程序 sips 下载它并得到相同的失真!然后我用 Adobe After Effects 试了一下,效果很好。然后我安装了 imagemagick,现在可以正常工作了。我仍然会将赏金奖励给任何能够解释为什么在所有这些方法中发生这种情况的人。
编辑#3
根据要求,这是缩放和未缩放的精灵贴图的一部分。在创建这些过程中,我发现 OSX 的内置 "Preview" 应用程序在缩小时也会导致缩放问题,所以我实际上不得不使用 photoshop 来获取原始剪辑。
原文:
缩放失真。尝试沿水平轴观察绿色通道
请注意,这些剪裁并不是完全相同的像素,而是从形状中看到的相同区域剪裁的
编辑 #4
我现在已经尝试在应用程序中通过 OpenGL 进行这种缩放,我发现它也发生在那里!这与使用固定位数进行双线性插值的一些基本问题有关?
使用 skimage 缩放 50% 时,以下代码似乎可以正确执行操作:
import numpy
import skimage
import skimage.io
img = skimage.io.imread('uY173.png')
import skimage.transform
img50_order0 = skimage.img_as_ubyte( skimage.transform.rescale(img, 0.5, order=0, clip=True) )
img50_order1 = skimage.img_as_ubyte( skimage.transform.rescale(img, 0.5, order=1, clip=True) )
img50_lm = numpy.rint( skimage.transform.downscale_local_mean(img, (2,2,1), clip=True) )
import scipy.ndimage.interpolation
img50_nd = scipy.ndimage.interpolation.zoom(img, (0.5, 0.5, 1))
# plot section of green channel along horizontal axis
plot(img50_order0[50, :, 1])
plot(img50_order1[50, :, 1])
plot(img50_lm[50, :, 1])
plot(img50_nd[50, :, 1])
这(据我所知)并不依赖于引擎盖下的 PIL。源图像被读取为 uint8,在每个图像中以略微不同的方式进行处理和舍入,从而产生 uint8 输出。但是,所有这些之间的差异永远不会超过 1,并且步长永远不会超过 2。