如何在sk-image中调整图像大小但保持像素值不变?

5

我想调整图片的大小。 我的图片包含特定的值[0、1、2、7、9]。 调整大小后,会引入新值,例如5等。 我想防止这种情况发生。

我目前正在使用scikit图像调整函数。 我尝试了所有的插值标志,但都无济于事。

编辑:一个简单的代码来展示问题:

import numpy as np
from skimage.transform import resize
vals = [0, 1, 4, 6]
N, M = 100, 100
image = np.random.choice(vals, N * M).reshape(N, M).astype('uint8')
resized_image = resize(image, (50, 50), preserve_range=True).astype('uint8')

print('vals before resizing ', np.unique(image))
print('vals after resizing ', np.unique(resized_image))

我猜如果你想保留原始像素值,结果图像将会有混叠现象。 - Saeed Masoomi
@SaeedMasoomi,没问题。 - Alex Deft
3个回答

3
anti_aliasing设置为False:
resized_image = resize(image, (50, 50), order=0, preserve_range=True, anti_aliasing=False).astype('uint8')

抗锯齿bool,可选
是否在缩小图像之前应用高斯滤波器以平滑图像。当对图像进行下采样以避免出现混叠伪影时,过滤是至关重要的。

混叠滤波器应用高斯滤波器,产生新值。


结果:

vals before resizing  [0 1 4 6]
vals after resizing  [0 1 4 6]

2
如果您想避免引入新的值,就需要避免使用线性、双线性、二次等“计算”类型的插值方法,而使用最近邻插值。这在调色板(即索引)图像和分类图像中尤为重要,因为每个数字代表一个类别,插值可能会在代表“森林”的类别和代表“高速公路”的相邻类别之间引入一些新值,从而构建出亚利桑那州的海滩!
这意味着在调整大小时,应使用order=0(对应于“最近邻”)而不是默认的order=1(对应于“双线性”)。
各种插值方法的详细说明在这里

我已经将order=0设置好了,但仍然引入了新的值。 - Alex Deft
请提供您代码的最小完整可验证示例 https://stackoverflow.com/help/minimal-reproducible-example ,我会看一下并尽力帮助您 :-) - Mark Setchell
我已经添加了一个简单的代码来展示问题。谢谢。 - Alex Deft
我即将离线,但在这里阅读关于 astype() https://scikit-image.org/docs/stable/user_guide/data_types.html 和同一页上稍后提到的preserve_range - Mark Setchell

1
你不想使用反锯齿,但是调整大小的函数默认会应用它(因此该函数将在图像上应用高斯核以消除锯齿),所以如果你想保留原始像素,必须通过 anti_aliasing=False 禁用此标志。
resized_image = resize(image, (50, 50), preserve_range=True, anti_aliasing=False,order=0).astype('uint8')

通过这个变化,输出将会是:
vals before resizing  [0 1 4 6]
vals after resizing  [0 1 4 6]

通过查看resize函数文档,我们可以看到高斯核只有在调整大小的图像比原始图像小时才会应用。(这就是你的情况)

anti_aliasing布尔值,可选

是否在缩小图像之前应用高斯滤波器以平滑图像。在缩小图像以避免混叠伪影时,过滤是至关重要的。


“当你的调整大小后的图像比原始图像大时,高斯核函数才会应用”这个说法是不正确的。” - Wodzu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接