How to use matlab imresize in python

I am passing Matlab imresize code in python. I found scipy imresize , but I got different results from Matlab.

How to get the same results as Matlab in 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.

+7
source share
3 answers

The scipy.misc.imresize function is a little strange for me. First, this is what happens when I specify the image of the 2D image that you provided to call scipy.misc.imresize this image with a scale of 1.0. Ideally, it should give you the same image, but we get 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) 

It not only changes the type of output to uint8 , but also scales the values. Firstly, it looks like the maximum value of the image is 255, and the minimum value is 0. MATLAB imresize does not do this and imresize image as 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 know that MATLAB performs resizing with anti-aliasing enabled by default . I'm not sure scipy.misc.resize here, but I bet that anti-aliasing is not turned on.

Edit - November 23, 2016

As Eric noted in his comments below, if you pre-draw the image on 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) 

We see that the image does not scale to the range [0,255] . To finally get where you need to go, we need to get a floating-point representation of the image. scipy.misc.imresize has an additional flag named 'mode' , and you can specify it as 'F' to ensure that the output is a 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) 

As you will see below, the results that you see with scipy.misc.resize do not match what you see in MATLAB.

For best results, do not specify the scale - specify the target output size for reproducing the results. So 1/scale in your case is close to a 2 x 2 output, and here is 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 

You can see that some of the values ​​in the matrix do not align with scipy.misc.resize . To match what you see in MATLAB. Closest to what you want is OpenCV resize or scikit-image resize . Both of them have no smoothing. If you want both Python and MATLAB to match, use the bilinear interpolation method. imresize in MATLAB uses bicubic interpolation by default, and I know that MATLAB uses custom kernels for this, and therefore it will be much more difficult to compare their results if you use bicubic interpolation between these methods. See this post for more informative results:

MATLAB vs C ++ vs OpenCV - imresize

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

It is interesting to note that MATLAB, OpenCV, and the scikit image, when defining a floating point scale, act differently with each other. I did some experiments and, indicating the size of the floating point, I could not find the results. In addition, scikit-image does not support the adoption of a scale factor, which is more a basis for explicitly indicating the size of the output, rather than the scale.

+11
source

To add another parameter, I found while studying a great answer from @rayryeng .

scipy.misc.imresize uses PIL (and therefore converts the image to scaled integers). But the page links to another function: 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]]) 

This does not give me the same result as matlab, but it is close:

 >> dtest = [1,2,3;4,5,6;7,8,9]; >> imresize(dtest, [2,2]) ans = 2.1296 3.5648 6.4352 7.8704 

Depending on what you want to achieve, this may be useful. For me, this has the advantage of not having to include another project in the project, since scipy is already in use.

+2
source

Good day to everyone, this is not an answer, but a question. What to do if the dtest user3960019 variable contains a matrix such as:

 [[ 0.14417706 0.18959087 0.2234258 ..., 0.16840368 0.15120561 0.11965712] [ 0.19098209 0.25031347 0.29384765 ..., 0.21637971 0.19531406 0.1554829 ] [ 0.22742296 0.29720085 0.34758183 ..., 0.24855714 0.22531588 0.1804396 ] 

Is this OpenCV change still better or doing something good? Since opensv resize returns an error like

 TypeError: src is not a numerical tuple 

or

 SystemError: new style getargs format but argument is not a tuple 
0
source

All Articles