Python implementation of MatLab imresize() function.
In the latest Super Resolution challenges (e.g. see NTIRE 2017) the downscaling - bicubic interpolation - is performed via MatLab imresize() function.
Track 1: bicubic uses the bicubic downscaling (Matlab imresize), one of the most common settings from the recent single-image super-resolution literature.
For obtaining the low res images we use the Matlab function "imresize" with default settings (bicubic interpolation) and the desired downscaling factors: 2, 3, and 4.
Moreover, the quality (PSNR) of a tested solution is compared with the reference solution - upsampling with bicubic interpolation - which is done again with MatLab imresize() function with the default settings.
All this leads to:
As the most of the Deep Learning code is written under the python, we need to do some additional preprocessing/postprocessing using completely different environment (MatLab), and can't do upscaling/downscaling in-place using simple python functions. As a result, the implemented python imresize() function is done to overcome these difficulties.
imresize of uint8 image using scale (e.g. 0.5 or 2):
Img_out = imresize(Img_in, scalar_scale=0.333) # Img_out of type uint8
imresize of uint8 image using shape (e.g. (100, 200)):
Img_out = imresize(Img_in, output_shape=(123, 324)) # Img_out of type uint8
Above examples are working when input image Img_in
is of the type uint8. But often the image processing is done in float64, and converted to uint8 only before saving on disk. The following code is for obtaining the same result as doing imresize+imwrite in MatLab for input image of doubles:
import numpy as np
from skimage.io import imsave, imread
from skimage import img_as_float
img_uint8 = imread('test.png')
img_double = img_as_float(img_uint8)
new_img_double = imresize(img_double, output_shape=(123, 324))
imsave('test_double.png', convertDouble2Byte(new_img_double))
Actually, the implemented python code was made by re-writing MatLab code toolbox/images/images/imresize.m
, and it can't be done without brilliant insight made by S. Sheen about how imresizemex
can be implemented (originally, it is binary provided with MatLab distribution): stackoverflow.
In fact, if you have OpenCV and have the ability to re-compile it, probably the best solution is to change parameter A
inside function interpolateCubic
, which is located (at least for release 3.2.0) on line 3129
inside file opencv-3.2.0/modules/imgproc/src/imgwarp.cpp
, from -0.75f to -0.5f (the value used in MatLab). Then simply use function cv::resize
from OpenCV. For more information please refer to stackoverflow. Also, see another stackoverflow answer about different ways of resizing the image inside python.
Please note that no optimization (aside from preliminary numpy-based vectorizing) was made, so the code can be (and it is) times slower than the original MatLab code.