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
Is There Any Alternative to Using % (Modulus) in C/C++
How to Find the Intersection of Two Stl Sets
How to Define Several Include Path in Makefile
Use Std::Fill to Populate Vector with Increasing Numbers
Differencebetween Imagemagick and Graphicsmagick
What Is the Default Hash Function Used in C++ Std::Unordered_Map
Recursively Iterate Over All the Files in a Directory and Its Subdirectories in Qt
Converting a Variable Name to a String in C++
When Should Your Destructor Be Virtual
How to Use the Mingw Gdb Debugger to Debug a C++ Program in Windows
How to Play or Open *.Mp3 or *.Wav Sound File in C++ Program
How to Deal with "Signed/Unsigned Mismatch" Warnings (C4018)
Why Is 'Std::Initializer_List' Often Passed by Value
Obtain a Std::Ostream Either from Std::Cout or Std::Ofstream(File)