如何在python中使用Matlab的imresize
image
image-processing
matlab
python
4
0

我正在将Matlab的imresize代码转移到python中。我发现scipy imresize ,但是从Matlab得到了不同的结果。

如何通过python获得与Matlab相同的结果。

Python / 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)

Matlab imresize

dtest = [1,2,3;
         4,5,6;
         7,8,9];
scale = 1.4;
dim = imresize(dtest,1/scale);

这两段代码返回不同的结果。

参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

在探索@rayryeng出色答案的同时,我发现了另外一个选择。

scipy.misc.imresize使用PIL(因此将图像转换为缩放的整数)。但是页面链接到另一个功能: scipy.ndimage.zoom

>>> from scipy import ndimage
>>> dtest = np.array(([1,2,3],[4,5,6],[7,8,9]), dtype='float')
>>> ndimage.zoom(dtest, 2/3)
array([[ 1.,  3.],
       [ 7.,  9.]])
>>> ndimage.zoom(dtest, 2/3, prefilter=False)
array([[ 2.33333333,  3.66666667],
       [ 6.33333333,  7.66666667]])

它给我的结果与matlab不同,但是很接近:

>> dtest = [1,2,3;4,5,6;7,8,9];
>> imresize(dtest, [2,2])

ans =
    2.1296    3.5648
    6.4352    7.8704

根据您要实现的目标,这可能会很有用。对我来说,它的优点是无需包含其他项目包,因为已经使用了scipy。

收藏
评论

scipy.misc.imresize函数对我来说有点奇怪。一方面,这就是当我指定您提供给此图像的scipy.misc.imresize调用的样本2D图像时所发生的情况,缩放比例为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,而最小值等于imresizeimresize并不执行此操作,而是按照我们期望的方式调整了图像的大小:

>> 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不支持采用比例因子,这更是明确声明输出尺寸而非比例的原因。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号