如何在python中使用Matlab的imresize [英] How to use Matlab's imresize in python

查看:1098
本文介绍了如何在python中使用Matlab的imresize的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm transferring Matlab's imresize code into python. I found the scipy's imresize, but I get a different results from Matlab.

如何得到相同的结果matlab by python。

How to get the same results as Matlab by python.

Python / scipy imresize

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);

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

These two pieces of code return different results.

推荐答案

scipy.misc.imresize 函数对我来说有点奇怪。首先,当我在此图像上以1.0的比例指定您提供给 scipy.misc.imresize 的样本2D图像时,会发生这种情况。理想情况下,它应该给你相同的图像,但我们得到的是这个(在IPython中):

The scipy.misc.imresize function is a bit odd for me. For one thing, this is what happens when I specify the sample 2D image you provided to a scipy.misc.imresize call on this image with a scale of 1.0. Ideally, it should give you the same image, but what we get is this (in 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 不会这样做,它会调整图像的大小我们期望的方式:

Not only does it change the type of the output to uint8, but it scales the values as well. For one thing, it looks like it makes the maximum value of the image equal to 255 and the minimum value equal to 0. MATLAB's imresize does not do this and it resizes an image in the way we expect:

>> 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 ,但我敢打赌,没有启用抗锯齿功能。

However, you need to be cognizant that MATLAB performs the resizing with anti-aliasing enabled by default. I'm not sure what scipy.misc.resize does here but I'll bet that there is no anti-aliasing enabled.

正如Eric在下面的评论中指出的那样,如果您预先将图像转换为所需的类型,您将获得预期结果:

As noted by Eric in his comments below, if you pre-cast the image to the desired type, you will get the expected results:

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'确保输出为浮点。

We can see that the image is not scaled to the [0,255] range. To finally get where you need to go, we must obtain a floating-point representation of the image. scipy.misc.imresize has an additional flag called 'mode' and you can specify this as 'F' to ensure the output is floating point.

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中看到的不匹配。


As you will see later, the results that you see with scipy.misc.resize don't match with what you see in MATLAB.

为获得最佳结果,请勿指定比例 - 指定目标输出大小以重现结果。因此,在您的情况下, 1 / scale 接近 2 x 2 大小输出,所以这就是你的意思将在MATLAB中做:

For the best results, don't specify a scale - specify a target output size to reproduce results. As such, 1/scale in your case is close to a 2 x 2 size output, and so here's what you would do in 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的 调整大小 功能,或scikit-image的 调整大小 功能。这两者都没有抗锯齿。如果要使Python和MATLAB相互匹配,请使用双线性插值方法。 MATLAB中的 imresize 默认情况下使用双三次插值,我知道MATLAB使用自定义内核这样做,所以如果你匹配它们的输出会更加困难在方法之间使用双三次插值。有关更多信息性结果,请参阅此帖子:

You can see that some of the values in the matrix don't align with scipy.misc.resize. To match what you see in MATLAB. The closest thing to what you want is either OpenCV's resize function, or scikit-image's resize function. Both of these have no anti-aliasing. If you want to make both Python and MATLAB match each other, use the bilinear interpolation method. imresize in MATLAB uses bicubic interpolation by default and I know for a fact that MATLAB uses custom kernels to do so, and so it will be much more difficult to match their outputs if you use bicubic interpolation between the methods. See this post for some more informative results:

MATLAB vs C ++ vs OpenCV - imresize

使用Python OpenCV:

With 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:

With 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不支持采用比例因子,这更明显地说明了输出大小而不是比例。

One last interesting thing to note is that MATLAB, OpenCV and scikit-image when specifying a floating point scale act differently with each other. I did some experiments and by specifying a floating point size, I was unable to get the results to match. Besides which, scikit-image does not support taking in a scale factor which is more reason to explicitly state an output size rather than a scale.

这篇关于如何在python中使用Matlab的imresize的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆