2

I'm currently working on porting some code from Matlab to C++ and having some difficulty with image resizing. I'm using OpenCV to resize in C++, however the results do not match. I know about the anti-aliasing option in Matlab but in this case, I'm scaling up so Matlab doesn't use that option.

Matlab code:

imresize(a,1.3, 'bilinear')

C++ code:

double scale = 1.3;
cv::Mat a = (cv::Mat_<double>(5, 5) << 0.7430835, 0.2263354, 0.8372651, 0.4305077, 0.0060997,
                                       0.1850839, 0.4359681, 0.6224524, 0.3951009, 0.3335419,
                                       0.5295836, 0.0202813, 0.8555994, 0.3494351, 0.6370482,
                                       0.3154180, 0.4335316, 0.6281235, 0.3844186, 0.9898034,
                                       0.9576555, 0.0212430, 0.3106115, 0.2677145, 0.1495867);
cv::Mat b;
cv::Mat c;

cv::resize(a, b, cv::Size(), scale, scale, CV_INTER_LINEAR);

cv::resize(a, c, cv::Size(ceil(scale * 5), ceil(scale * 5)), 0, 0, CV_INTER_LINEAR);

I noticed that matrix b gave me the wrong dimensions, so in c I specified the dimensions instead of scale factor. Even though the dimensions is correct, it does not provide the same result:

Matlab:

a=
0.7430835   0.2263354   0.8372651   0.4305077   0.0060997
0.1850839   0.4359681   0.6224524   0.3951009   0.3335419
0.5295836   0.0202813   0.8555994   0.3494351   0.6370482
0.3154180   0.4335316   0.6281235   0.3844186   0.9898034
0.9576555   0.0212430   0.3106115   0.2677145   0.1495867

ans =
0.7430835   0.3985848   0.4299787   0.8372651   0.5660935   0.2890383   0.0060997
0.3710838   0.3677549   0.4754126   0.6940566   0.5026210   0.3460670   0.2243945
0.2999171   0.2982429   0.4316599   0.7001681   0.4866420   0.3981562   0.4347107
0.5295836   0.1900488   0.2987207   0.8555994   0.5181565   0.4453061   0.6370482
0.3868066   0.3261232   0.4318373   0.7039488   0.4831546   0.5392444   0.8722183
0.5294972   0.3739004   0.3714968   0.5222862   0.4044402   0.4669219   0.7097312
0.9576555   0.3333805   0.1176992   0.3106115   0.2820135   0.2283386   0.1495867

C++:

a:
0.743084 0.226335 0.837265 0.430508 0.0060997
0.185084 0.435968 0.622452 0.395101 0.333542
0.529584 0.0202813 0.855599 0.349435 0.637048
0.315418 0.433532 0.628123 0.384419 0.989803
0.957655 0.021243 0.310611 0.267715 0.149587

b:
0.743084 0.40521 0.484806 0.759043 0.446152 0.120363
0.378238 0.368538 0.50446 0.641146 0.41849 0.270586
0.330834 0.284585 0.455135 0.654686 0.389062 0.438749
0.488398 0.234284 0.401026 0.724221 0.373689 0.610999
0.323655 0.385105 0.510391 0.588065 0.392835 0.816538
0.784745 0.35811 0.243873 0.377449 0.302864 0.355159

c:
0.743084 0.447799 0.400887 0.837265 0.546724 0.248619 0.0060997
0.424227 0.379597 0.45138 0.714515 0.497201 0.317247 0.19321
0.283512 0.302763 0.423448 0.689066 0.469771 0.398427 0.420258
0.529584 0.238554 0.258944 0.855599 0.494054 0.472698 0.637048
0.376608 0.341666 0.423362 0.693117 0.465479 0.594963 0.889016
0.590663 0.399905 0.324039 0.492047 0.379444 0.460963 0.62971
0.957655 0.422563 0.10392 0.310612 0.279971 0.217088 0.149587

Unfortunately, I can not edit the Matlab code, so all the changes need to be done in C++. Does anyone know how to make OpenCV provide the same result as Matlab, or do I need to create my own function?

Best regards Sondre

Related SO questions:

MATLAB vs C++ vs OpenCV - imresize

why OpenCV cv2.resize gives different answer than MATLAB imresize?

imresize bilinear MATLAB

  • 1
    It looks non-trivial to me. The difference must be in the linear interpolation methods used by OpenCV and Matlab. It might be sligltly time-consuming, but you can have a look at the OpenCV implementation in `modules/imgproc/src/resize.cpp:4037` (it later delegates to hal::resize), and matlab implementation is of course available in `imresize.m` file. – pptaszni May 31 '18 at 14:05

2 Answers2

2

There is an important difference between the cv::resize and imresize. It's important to notice that

>> imresize(a, 1.3, 'bilinear')

ans =

    0.7431    0.4052    0.4848    0.7590    0.4462    0.1204    0.0061
    0.3782    0.3685    0.5045    0.6411    0.4185    0.2706    0.2202
    0.3308    0.2846    0.4551    0.6547    0.3891    0.4387    0.4619
    0.4884    0.2343    0.4010    0.7242    0.3737    0.6110    0.7049
    0.3237    0.3851    0.5104    0.5881    0.3928    0.8165    0.9762
    0.7847    0.3581    0.2439    0.3774    0.3029    0.3552    0.3758
    0.9577    0.3454    0.1437    0.3024    0.2694    0.1814    0.1496

and

>> imresize(a, ceil(size(a)*1.3), 'bilinear')

ans =

    0.7431    0.4478    0.4009    0.8373    0.5467    0.2486    0.0061
    0.4242    0.3796    0.4514    0.7145    0.4972    0.3172    0.1932
    0.2835    0.3028    0.4234    0.6891    0.4698    0.3984    0.4203
    0.5296    0.2386    0.2589    0.8556    0.4941    0.4727    0.6370
    0.3766    0.3417    0.4234    0.6931    0.4655    0.5950    0.8890
    0.5907    0.3999    0.3240    0.4920    0.3794    0.4610    0.6297
    0.9577    0.4226    0.1039    0.3106    0.2800    0.2171    0.1496

don't produce the same result. In the first case the image is truly scaled by a factor of 1.3 whereas in the second case the scaling is deduced by MATLAB and is in this case 5/3=1.6666. This can be understood like the following: if we provide a scale factor to the MATLAB function imresize the image is scaled with exactly that factor and the size of resized image is deduced (with ceil). If we provide the dimensions to imresize MATLAB use those to deduce the scale and thus we get a different result in the end.

OpenCV on the other hand uses uses round to deduce the resized image size if only the scale factors (fx and fy) are provided. According to the documentation of OpenCV it should be possible to provide dsize, fx and fy simultaneously and achieve a similar behavior as in MATLAB. Unfortunately the documentation seems to be wrong as stated in resize: cannot specify both size and fx/fy

Thus we can't exactly match the behavior of MATLAB with OpenCV without changing OpenCV source code.

T.Etti
  • 23
  • 6
0
height, width = img.shape[:2]
res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)

Scaling is just resizing of the image. OpenCV comes with a function cv.resize() for this purpose. The size of the image can be specified manually, or you can specify the scaling factor. Assuming you have read image in img variable. this was written in python. Hope this would help