为什么RGB图像上的python cv2.resize函数给出的结果与MATLAB imresize函数不同?

时间:2017-10-11 07:20:52

标签: python matlab opencv numpy image-processing

我正在将一个python脚本转移到MATLAB中。 python脚本中的一个步骤是使用cv2.resize函数将256 * 256 RGB图像的大小调整为40 * 40 RGB图像,即

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

并且,我在40 * 40图像中打印B通道的一些像素值。

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

然而,当我使用MATLAB imresize函数时,我的结果略有不同。 PS:我已将AntiAliasing设置为false,如上所述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

并提供测试图像0.png

期待任何有助于我的解释。

更新 - 2017年10月12日

正如 Ander Biguri 在下面的评论中所指出的,问题的原因可能是:插值给出浮点值,但我使用的是uint8值,这可能会导致舍入错误。

将图像矩阵转换为double类型,似乎是正确的。

使用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]]

使用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:问题How to use Matlab's imresize in python的答案在使用uint8值时未提及插值引起的舍入误差。

1 个答案:

答案 0 :(得分:1)

这是由于舍入错误造成的。请注意,所有差异仅为1个单位。

您正在使用uint8值,但插值几乎总是会给出浮点值。像素值[0 - 3]之间的中间点是1.5。根据{{​​1}}内进行的数学运算符的确切顺序,结果可能是resize1.4999999999999,然后在四舍五入时得到1.500000000000011

Read more about floating points maths