使用各种不同方法缩小缩放时,图像渐变变得不准确

时间:2016-03-26 05:48:40

标签: python numpy image-processing python-imaging-library

我们有一个用Python编写的相当复杂的图像处理脚本,它使用PIL和numpy。对于其中一个步骤,我们有一个非常敏感的多通道梯度,它是一个查找表。创建后,它将保存为多个不同的较小分辨率。然而,当发生这种情况时,绿色通道(从左到右延伸的梯度)突然出现失去优势。它应该每50个像素左右丢失255个值中的1个。相反,它每100像素开始下降2。这导致了巨大的问题,我无法弄清楚为什么PIL会这样做。但是,我确实在地图的其他部分看到了1的跳跃,所以我认为它不是一个简单的因为它缺少一点精度。我也注意到在另一个频道上,似乎整个地图都被移动了1个值。一旦缩放,整个事情似乎都是不准确的,即使使用“最近的”过滤器。

对于完整尺寸的图像,我们使用以下内容从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来下载它并获得相同的失真!然后我尝试使用Adobe After Effects,它运行良好。然后我安装了imagemagick,现在工作正常。我仍然会向任何可以解释为什么在所有这些方法中发生这种情况的人奖励赏金。

编辑#3

根据请求,这是一个缩放和未缩放的精灵地图的一部分。在创建这些过程中,我发现OSX内置的“预览”应用程序在缩小时也会导致缩放问题,因此我实际上不得不使用photoshop来获取原始剪辑。

原件:

enter image description here

扭曲变形。尝试沿水平轴观察绿色通道

enter image description here

请注意,这些剪辑不是完全相同的像素,而是从形状中看到的相同区域切割

编辑#4

我现在尝试在应用程序中通过OpenGL进行这种缩放,我发现它也发生在那里!这与使用固定位数进行双线性插值的一些基本问题有关吗?

1 个答案:

答案 0 :(得分:2)

使用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。