简体   繁体   中英

Why Does OpenCV Resize Give Different Pixel Values When Specifying Dsize vs. fx/fy?

Today I was surprised to discover that when using OpenCV-Python cv2.resize , I get different results from when I specify fx and fy , or when I do the dsize calculation myself and feed that.

Note that this is NOT about image size mismatch, but actual individual pixel value difference.

import cv2
import numpy as np

scale = 0.55
image = np.arange(100).reshape(10, 10).astype(np.float)
resized_fx_fy = cv2.resize(image, None, fx=scale, fy=scale, interpolation=cv2.INTER_LINEAR)
resize_height, resize_width = resized_fx_fy.shape
resized_dsize = cv2.resize(image, (resize_width, resize_height), interpolation=cv2.INTER_LINEAR)
print(np.abs(resized_fx_fy - resized_dsize).max())
7.499998092651367
print(resized_fx_fy - resized_dsize)
[[0.83333344 0.98484851 1.13636362 1.28787897 1.43939408 1.09090917]
 [2.34848631 2.50000024 2.65151525 2.80303049 2.9545455  2.6060605 ]
 [3.86363742 4.01515031 4.16666532 4.31818056 4.46969557 4.12121058]
 [5.37879091 5.53030276 5.68181777 5.83333302 5.98484802 5.63636303]
 [6.89394202 7.04545283 7.19696784 7.34848309 7.49999809 7.1515131 ]
 [3.40909298 3.5606029  3.71211791 3.86363316 4.01514816 3.66666317]]

From a naive interpretation of the opencv docs, these should be equivalent but clearly they are not.

A possible hint: The above code yields no difference when scale = 0.5

In case it's relevant:

Python 3.8.5

opencv-contrib-python     4.2.0.34                 pypi_0    pypi
opencv-python             4.2.0.34                 pypi_0    pypi
opencv-python-headless    4.5.1.48                 pypi_0    pypi

cv::resize is an affine transformation that maps integer indices from the destination image to floating point indices in the source image and uses the interpolation method to calculate the value. Because it is an affine transformation, the scale parameter is the most important parameter in determining the exact output values.

According to the OpenCV source code for cv::resize() , if dsize is provided, fx and fy (referred to as inv_scale_x and inv_scale_y in c++ source code) are overwritten with relative scale of output to input, regardless of whether fx or fy are zero or not. In your example, the first cv.resize() uses inv_scale_x and inv_scale_y of 0.55. The second cv.resize() uses 0.6 for these two scale parameters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM