2

I'm transferring a python script into MATLAB one. One step in python script is to resize a 256*256 RGB image to 40*40 RGB image, using cv2.resize function, i.e.

import cv2
img = cv2.imread('0.png')
img_40 = cv2.resize(img, (40, 40)) # img rescaled to 40*40

And, I print some pixel values of B channel in 40*40 image.

print img_40[0:10, 0:10, 0] 
ans = 
[[  0   0   1   2   1   3   0  21  96 128]
[  2   0  17  13   5  20  15  48 112 126]
[  0   0   6   0   2   3  80 107 122 129]
[  0   5   1   7   0  14  98 132 129 127]
[  1   2   0   0   0  16 100 151 138 134]
[  0   2   0   2   0  34 105 138 143 139]
[  0   3   0   0   0  54  96  29  51  79]
[  5   0   0   0   0  56 118 103  97  38]
[  3   0   0   0   2  44 132  95  93  89]
[  1   0   1   3   0  38 141 128 104  26]]

However, when I use MATLAB imresize function, I got a slightly different result. PS: I have set the AntiAliasing to false as mentioned here.

img = imread('0.png');
img_40 = imresize(img,[40,40],'bilinear','AntiAliasing',false);
img_40(1:10,1:10,3)
ans = 
0    0    2    1    2    4    0   21   96  128
2    0   18   13    5   20   15   48  112  127
0    0    6    0    3    3   81  107  123  129
0    5    1    7    0   14   99  133  129  127
1    2    0    0    0   16  100  151  139  134
0    2    0    2    0   34  105  139  144  140
0    3    0    0    0   54   96   29   51   79
6    0    0    0    0   57  119  104   97   39
3    0    0    0    2   44  132   96   93   89
1    0    1    3    1   38  141  129  104   26

And provide test image 0.png

Looking forward to any explanation that will help me.

Update- October 12th, 2017

As noted by Ander Biguri in his comments below, the reason for the problem may be: the interpolation gives float values, but I am working with uint8 values, which may cause rounding error.

And convert the image matrix to double type, it seems correct.

With python cv2:

img = cv2.imread('0.png')
d_img = img.astype('float')
img_40 = cv2.resize(d_img, (40, 40)) # img rescaled to 40*40
print img_40[0:10, 0:10, 0]
ans = 
[[  3.00000000e-01   0.00000000e+00   1.40000000e+00   1.81000000e+00
1.61000000e+00   3.49000000e+00   0.00000000e+00   2.13500000e+01
9.62500000e+01   1.28080000e+02]
[  2.00000000e+00   0.00000000e+00   1.75000000e+01   1.31900000e+01
4.87000000e+00   1.98900000e+01   1.52300000e+01   4.81500000e+01
1.12420000e+02   1.26630000e+02]
[  0.00000000e+00   0.00000000e+00   5.75000000e+00   0.00000000e+00
2.35000000e+00   2.80000000e+00   8.04000000e+01   1.06500000e+02
1.22300000e+02   1.28800000e+02]
[  0.00000000e+00   5.28000000e+00   9.50000000e-01   7.19000000e+00
0.00000000e+00   1.40300000e+01   9.85100000e+01   1.32200000e+02
1.28990000e+02   1.27270000e+02]
[  7.90000000e-01   2.40000000e+00   1.50000000e-01   7.00000000e-02
0.00000000e+00   1.65100000e+01   9.96300000e+01   1.50750000e+02
1.38440000e+02   1.34300000e+02]
[  0.00000000e+00   2.13000000e+00   1.50000000e-01   1.90000000e+00
0.00000000e+00   3.42900000e+01   1.04730000e+02   1.38400000e+02
1.43560000e+02   1.39400000e+02]
[  0.00000000e+00   2.70000000e+00   0.00000000e+00   0.00000000e+00
0.00000000e+00   5.43700000e+01   9.57400000e+01   2.88500000e+01
5.05500000e+01   7.88600000e+01]
[  5.55000000e+00   0.00000000e+00   0.00000000e+00   0.00000000e+00
1.50000000e-01   5.65500000e+01   1.18500000e+02   1.03000000e+02
9.73000000e+01   3.81000000e+01]
[  3.30000000e+00   0.00000000e+00   0.00000000e+00   0.00000000e+00
1.84000000e+00   4.40700000e+01   1.32280000e+02   9.53000000e+01
9.27000000e+01   8.92400000e+01]
[  1.40000000e+00   0.00000000e+00   1.00000000e+00   3.03000000e+00
7.00000000e-01   3.79900000e+01   1.40600000e+02   1.28600000e+02
1.04270000e+02   2.61200000e+01]]

With MATLAB:

img = imread('0.png');
d_img = single(img);
img_40 = imresize(d_img,[40,40],'bilinear','AntiAliasing',false);
img_40(1:10,1:10,3)

0.3000         0    1.4000    1.8100    1.6100    3.4900         0   21.3500   96.2500  128.0800
2.0000         0   17.5000   13.1900    4.8700   19.8900   15.2300   48.1500  112.4200  126.6300
     0         0    5.7500         0    2.3500    2.8000   80.4000  106.5000  122.3000  128.8000
     0    5.2800    0.9500    7.1900         0   14.0300   98.5100  132.2000  128.9900  127.2700
0.7900    2.4000    0.1500    0.0700         0   16.5100   99.6300  150.7500  138.4400  134.3000
     0    2.1300    0.1500    1.9000         0   34.2900  104.7300  138.4000  143.5600  139.4000
     0    2.7000         0         0         0   54.3700   95.7400   28.8500   50.5500   78.8600
5.5500         0         0         0    0.1500   56.5500  118.5000  103.0000   97.3000   38.1000
3.3000         0         0         0    1.8400   44.0700  132.2800   95.3000   92.7000   89.2400
1.4000         0    1.0000    3.0300    0.7000   37.9900  140.6000  128.6000  104.2700   26.1200

PS: answers to the question How to use Matlab's imresize in python do not mention the rounding error caused by interpolation, when working with uint8 values.

7color
  • 23
  • 5

1 Answers1

2

This is due to rounding error. Note that all differences are just of 1 unit.

You are working with uint8 values, however the interpolation will almost always give float values. the middle point between the pixel values [0 - 3] is 1.5. Depending on the exact order of the math operators going on inside resize, the result may have been 1.4999999999999 or 1.50000000000001, and then when rounding you'd get 1 or 2.

Read more about floating points maths

Ander Biguri
  • 35,140
  • 11
  • 74
  • 120
  • 1
    Thank you very much, your answer solved my problem. And see updates in the question for details. – 7color Oct 12 '17 at 01:51