Matlab VS C++ VS Opencv - Imresize

MATLAB vs C++ vs OpenCV - imresize

Yes, just be aware that MATLAB's imresize has anti-aliasing enabled by default:

imresize(A,scale,'bilinear')

vs. what you would get with cv::resize(), which does not have anti-aliasing:

imresize(A,scale,'bilinear','AntiAliasing',false)

And as Amro mentioned, the default in MATLAB is bicubic, so be sure to specify.

Bilinear

No code modifications are necessary to get matching results with bilinear interpolation.

Example OpenCV snippet:

cv::Mat src(4, 4, CV_32F);
for (int i = 0; i < 16; ++i)
src.at<float>(i) = i;

std::cout << src << std::endl;

cv::Mat dst;
cv::resize(src, dst, Size(0, 0), 0.5, 0.5, INTER_LINEAR);

std::cout << dst << std::endl;

Output (OpenCV)

[0, 1, 2, 3;
4, 5, 6, 7;
8, 9, 10, 11;
12, 13, 14, 15]

[2.5, 4.5;
10.5, 12.5]

MATLAB

>> M = reshape(0:15,4,4).';
>> imresize(M,0.5,'bilinear','AntiAliasing',true)
ans =
3.125 4.875
10.125 11.875
>> imresize(M,0.5,'bilinear','AntiAliasing',false)
ans =
2.5 4.5
10.5 12.5

Note that the results are the same with anti-aliasing turned off.

Bicubic Difference

However, between 'bicubic' and INTER_CUBIC, the results are different on account of the weighting scheme! See here for details on the mathematical difference. The issue is in the interpolateCubic() function that computes the cubic interpolant's coefficients, where a constant of a = -0.75 is used rather than a = -0.5 like in MATLAB. However, if you edit imgwarp.cpp and change the code :

static inline void interpolateCubic( float x, float* coeffs )
{
const float A = -0.75f;
...

to:

static inline void interpolateCubic( float x, float* coeffs )
{
const float A = -0.50f;
...

and rebuild OpenCV (tip: disable CUDA and the gpu module for short compile time), then you get the same results:

MATLAB

>> imresize(M,0.5,'bicubic','AntiAliasing',false)
ans =
2.1875 4.3125
10.6875 12.8125

OpenCV

[0, 1, 2, 3;
4, 5, 6, 7;
8, 9, 10, 11;
12, 13, 14, 15]
[2.1875, 4.3125;
10.6875, 12.8125]

More about cubic HERE.

OpenCV image resize comparison to matlab

That change to OpenCV only makes the interpolation kernels' formulas match. It does not enable anti-aliasing. The result here will match with

imresize(A,scale,'bicubic','AntiAliasing',false)

To match the default, you'd need to further modify the kernel, making it broader.

openCV vs matlab matrix concatination

You're pretty close. I would use cv::merge. In fact, its very purpose is to merge single channel matrices (2D) into one multi-channel matrix (3D).

As such, instead of cv::hconcat, try just:

cv::merge(tempVec, d);

rehshape image to 3 columns matrix matlab vs openCV

This code:

int newRows = accum1r.rows * accum1r.cols;
int dims[2] = {newRows,3};
cv::Mat planes[] = {cv::Mat::zeros(newRows,1, CV_32F), cv::Mat::zeros(newRows,1, CV_32F), cv::Mat::zeros(newRows,1, CV_32F)};
cv::split(accum1r,planes);
planes[0] = planes[0].t();
planes[0] = planes[0].reshape(1,2,dims);
planes[1] = planes[1].t();
planes[1] = planes[1].reshape(1,2,dims);
planes[2] = planes[2].t();
planes[2] = planes[2].reshape(1,2,dims);
cv::merge(planes,3,accum1r);

can be rewritten as:

accum1r = accum1r.reshape(3, 1).t();

You can then get a newRows x 3 x 1 matrix timeMeanUnsorted as in Matlab using:

cv::Mat timeMeanUnsorted = accum1r.reshape(1) / numberOfFrames;

If you want instead a newRows x 1 x 3 (3 channel) matrix you can simply:

cv::Mat timeMeanUnsorted = accum1r / numberOfFrames;

OpenCV col-wise standard deviation result vs MATLAB

The standard deviation you're calculating in OpenCV is normalised by number of observations (N) whereas you're calculating standard deviation in MATLAB normalised by N-1 (which is also the default normalisation factor in MATLAB and is known as Bessel's correction). Hence there is the difference.

You can normalise by N in MATLAB by selecting the second input argument as 1:

Col_step_1 = std(A, 1, 1); 
Col_final = std(Col_step_1, 1);

Trying to implement a tiny part of matlab code in C++ using opencv

please stay away from accessing Mat's raw 'data' pointer, and use:

grey.at<double>(i,j);

instead.

also, if im_re is a 1 channel, grayscale image, your typeflag is wrong, should be:

img_re.convertTo( grey, CV_64F, 1.0/255.0 );


Related Topics



Leave a reply



Submit