user3960019 - 3 months ago 71

Python Question

I'm transferring Matlab's

`imresize`

`imresize`

How to get the same results as Matlab by python.

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.

Answer

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

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
```

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.

As such, I probably would not use `scipy.misc.imresize`

. 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`

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. See this post for some more informative results:

MATLAB vs C++ vs OpenCV - imresize

For the best results, don't specify a scale - specify a target output size to reproduce results. 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.

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
```

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. ]])
```

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. ]])
```