scipy.misc.imresize
函数对我来说有点奇怪。一方面,当我将您提供的示例2D图像指定为scipy.misc.imresize
调用中的图像,并将其缩放比例设置为1.0时,会发生以下情况。理想情况下,它应该给出相同的图像,但我们得到的是这样的(在IPython中):
In [35]: from scipy.misc import imresize
In [36]: import numpy as np
In [37]: dtest = np.array(([1,2,3],[4,5,6],[7,8,9]))
In [38]: out = imresize(dtest, 1.0)
In [39]: out
Out[39]:
array([[ 0, 32, 64],
[ 96, 127, 159],
[191, 223, 255]], dtype=uint8)
不仅将输出类型更改为
uint8
,还会对值进行
缩放。首先,它似乎使图像的最大值等于255,最小值等于0。MATLAB的
imresize
没有这样做,它按我们期望的方式调整图像大小:
>> dtest = [1,2,3;4,5,6;7,8,9];
>> out = imresize(dtest, 1)
out =
1 2 3
4 5 6
7 8 9
然而,您需要知道MATLAB默认启用抗锯齿功能进行调整大小(即平滑边缘)。我不确定scipy.misc.resize
在这里做了什么,但我敢打赌这里没有启用抗锯齿功能。
编辑-2016年11月23日
正如Eric在下面的评论中所指出的那样,如果您将图像预先转换为所需类型,则会获得预期的结果:
In [10]: dtest = np.array([[1,2,3],[4,5,6],[7,8,9]], dtype=np.uint8)
In [11]: out = imresize(dtest, 1.0)
In [12]: out
Out[12]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]], dtype=uint8)
我们可以看到该图像没有缩放到
[0,255]
范围内。为了最终达到目标,我们必须获得图像的浮点表示。
scipy.misc.imresize
还有一个额外的标志叫做
'mode'
,您可以将其指定为
'F'
以确保输出为浮点数。
In [14]: scale = 1.4
In [15]: out = imresize(dtest, 1/scale, mode='F')
In [16]: out
Out[16]:
array([[ 2.5 , 3.75],
[ 6.25, 7.5 ]], dtype=float32)
如您所见,使用
scipy.misc.resize
得到的结果与MATLAB中的不一致。
为了获得最佳结果,请勿指定比例 - 指定目标输出大小以重现结果。因此,在您的情况下,
1/scale
接近于
2 x 2
大小的输出,因此在MATLAB中可以这样做:
>> dtest = [1,2,3;4,5,6;7,8,9];
>> out = imresize(dtest, [2,2], 'bilinear', 'AntiAliasing', false)
out =
2.0000 3.5000
6.5000 8.0000
您可以看到矩阵中的一些值与scipy.misc.resize
不对齐。为了匹配MATLAB中所见到的内容,最接近您想要的是使用OpenCV的resize
函数或者scikit-image的resize
函数。这两个函数都没有反锯齿处理。如果您想让Python和MATLAB彼此匹配,请使用双线性插值方法。在MATLAB中,imresize
默认使用双三次插值,我知道MATLAB使用自定义内核来实现,因此如果在方法之间使用双三次插值,将更加困难地匹配它们的输出。请参考此帖子以获得更多有用的结果:
MATLAB vs C++ vs OpenCV - imresize
使用Python的OpenCV:
In [93]: import numpy as np
In [94]: import cv2
In [95]: dtest = np.array(([1,2,3],[4,5,6],[7,8,9]), dtype='float')
In [96]: out = cv2.resize(dtest, (2,2))
In [97]: out
Out[97]:
array([[ 2. , 3.5],
[ 6.5, 8. ]])
使用scikit-image:
In [100]: from skimage.transform import resize
In [101]: dtest = np.array(([1,2,3],[4,5,6],[7,8,9]), dtype='uint8')
In [102]: out = resize(dtest, (2,2), order=1, preserve_range=True)
In [103]: out
Out[103]:
array([[ 2. , 3.5],
[ 6.5, 8. ]])
值得注意的是,当指定浮点比例时,MATLAB、OpenCV和scikit-image的行为是不同的。我进行了一些实验,通过指定浮点大小,我无法使结果匹配。此外,scikit-image不支持输入比例因子,这更加需要明确地指定输出大小而不是比例。