如何在python中使用Matlab的imresize

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这里有什么,但我敢打赌,没有启用抗锯齿功能.

编辑 - 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)
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使用自定义内核这样做的事实,因此如果在方法之间使用双三次插值,匹配它们的输出会更加困难.有关更多信息性结果,请参阅此帖子:

MATLAB与C++对比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. ]])
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不支持获取比例因子,这更明显地表示输出大小而不是比例.

  • 我使用你说的方法,我得到相同的输出.谢谢你. (3认同)
  • 非常有趣的背景信息! (2认同)