本文介绍了MATLAB vs C ++ vs OpenCV - imresize的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的MATLAB代码,我想传送到C ++



假设 Gr 是二维矩阵 1 / newscale == 0.5

  Gr = imresize / newScale); 

在:

所以这意味着我将得到一个二维矩阵== matrix_width / 2和matrix_height / 2

如何计算值?根据文档的默认值来自最接近的4X4的立方插值。



我找不到C ++的示例代码也是这样。您能否提供此类代码的链接?



我还发现了有:

  imresize(A,scale,'bilinear')

vs。你将会得到 cv :: resize(),它没有抗锯齿:

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

正如Amro所说,MATLAB中的默认值是 bicubic ,所以一定要指定。



Bilinear



无需修改代码即可获得双线性插值的匹配结果。



示例OpenCV代码段:

  cv :: Mat src(4,4,CV_32F); 
for(int i = 0; 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;

输出(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 b
$ b

 >> M =重塑(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

请注意,关闭抗锯齿后,结果是一样的。



Bicubic区别



但是,在'bicubic' INTER_CUBIC 之间,结果是不同的帐户的加权计划!有关数学差异的详细信息,请参阅。问题在于计算立方内插器系数的 interpolateCubic()函数,其中常数 a = -0.75 而不是像在MATLAB中的 a = -0.5 。但是,如果您编辑imgwarp.cpp并更改代码:

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

到:

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

并重建OpenCV(提示:禁用CUDA和gpu模块编译时间),则得到相同的结果:



MATLAB

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

OpenCV

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

有关cubic 。


I have the following MATLAB code which I want to transport into C++

Assume Gr is 2d matrix and 1/newscale == 0.5

Gr = imresize(Gr, 1 / newScale);

in the MATLAB documentation:

So this means I will get a 2D matrix == matrix_width/2 and matrix_height/2
How do I calculate the values? The default according to the docs are coming from cubic interpolation for nearest 4X4.

I can't find a sample code for C++ that does the same. Can you please provide a link to such code?

I also found this OpenCV function, resize.

Does it do the same as the MATLAB one?

解决方案

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.

这篇关于MATLAB vs C ++ vs OpenCV - imresize的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 13:33