use*_*019 8 python matlab image image-processing scipy
我正在将Matlab的imresize代码转换为python.我找到了scipy imresize,但是我从Matlab得到了不同的结果.
如何通过python获得与Matlab相同的结果.
蟒蛇/ SciPy的 imresize
from scipy.misc import imresize
import numpy as np
dtest = np.array(([1,2,3],[4,5,6],[7,8,9]))
scale = 1.4
dim = imresize(dtest,1/scale)
Run Code Online (Sandbox Code Playgroud)
MATLAB imresize
dtest = [1,2,3;
4,5,6;
7,8,9];
scale = 1.4;
dim = imresize(dtest,1/scale);
Run Code Online (Sandbox Code Playgroud)
这两段代码返回不同的结果.
ray*_*ica 14
这个scipy.misc.imresize功能对我来说有点奇怪.首先,当我指定您scipy.misc.imresize在此图像上以1.0为标度调用时提供的样本2D图像时,会发生这种情况.理想情况下,它应该给你相同的图像,但我们得到的是这个(在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)
Run Code Online (Sandbox Code Playgroud)
它不仅改变输出的类型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
Run Code Online (Sandbox Code Playgroud)
但是,您需要认识到MATLAB在默认情况下启用了抗锯齿的情况下执行调整大小.我不确定scipy.misc.resize这里有什么,但我敢打赌,没有启用抗锯齿功能.
正如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)
Run Code Online (Sandbox Code Playgroud)
我们可以看到图像没有缩放到[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)
Run Code Online (Sandbox Code Playgroud)
正如您稍后将看到的,您看到的结果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
Run Code Online (Sandbox Code Playgroud)
您可以看到矩阵中的某些值与之不对齐scipy.misc.resize.与您在MATLAB中看到的相匹配.最接近你想要的是OpenCV的resize功能,或scikit-image的resize功能.这两者都没有抗锯齿.如果要使Python和MATLAB相互匹配,请使用双线性插值方法. imresize在MATLAB中默认使用双三次插值,我知道MATLAB使用自定义内核这样做的事实,因此如果在方法之间使用双三次插值,匹配它们的输出会更加困难.有关更多信息性结果,请参阅此帖子:
使用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. ]])
Run Code Online (Sandbox Code Playgroud)
使用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. ]])
Run Code Online (Sandbox Code Playgroud)
最后一个值得注意的事情是,在指定浮点刻度时,MATLAB,OpenCV和scikit-image的行为彼此不同.我做了一些实验,并通过指定浮点大小,我无法得到匹配的结果.除此之外,scikit-image不支持获取比例因子,这更明显地表示输出大小而不是比例.