MATLAB与C++对比OpenCV - imresize

Gil*_*lad 5 c++ matlab interpolation opencv image-processing

我有以下MATLAB代码,我想传输到C++

假设Gr是2d矩阵和1/newscale == 0.5

Gr = imresize(Gr, 1 / newScale);
Run Code Online (Sandbox Code Playgroud)

MATLAB文档中:

B = imresize(A,scale)返回图像B,其是尺寸乘以A的尺寸.输入图像A可以是灰度,RGB或二值图像.如果scale在0和1.0之间,则B小于A.如果scale大于1.0,则B大于A.

所以这意味着我将得到一个2D矩阵== matrix_width/2和matrix_height/2
如何计算这些值?根据文档的默认值来自最接近的4X4的三次插值.

我找不到C++的示例代码.你能提供这些代码的链接吗?

我也发现了这个OpenCV函数resize.

它和MATLAB一样吗?

cha*_*pjc 14

是的,请注意默认情况下 MATLAB的抗锯齿功能imresize启用:

imresize(A,scale,'bilinear')
Run Code Online (Sandbox Code Playgroud)

与你会得到的cv::resize(),没有抗锯齿:

imresize(A,scale,'bilinear','AntiAliasing',false)
Run Code Online (Sandbox Code Playgroud)

正如Amro所提到的,MATLAB中的默认值是bicubic,所以一定要指定.

双线性

使用双线性插值获得匹配结果不需要代码修改.

示例OpenCV片段:

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;
Run Code Online (Sandbox Code Playgroud)

输出(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]
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

请注意,关闭抗锯齿的结果是相同的.

双立方差异

然而,在'bicubic'和之间INTER_CUBIC,由于加权方案,结果是不同的! 有关数学差异的详细信息,请参见此处.问题interpolateCubic()在于计算三次插值系数的函数,其中使用常数a = -0.75而不是a = -0.5MATLAB 中的常数.但是,如果您编辑imgwarp.cpp并更改代码:

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

至:

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

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

MATLAB

>> imresize(M,0.5,'bicubic','AntiAliasing',false)
ans =
                    2.1875                    4.3125
                   10.6875                   12.8125
Run Code Online (Sandbox Code Playgroud)

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]
Run Code Online (Sandbox Code Playgroud)

更多关于立方HERE.