MATLAB与C ++对比OpenCV - imresize

时间:2014-11-08 00:25:43

标签: c++ matlab opencv image-processing interpolation

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

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

Gr = imresize(Gr, 1 / newScale);
the MATLAB documentation中的

  

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 ++的示例代码。你能提供这些代码的链接吗?

我还找到了this OpenCV function, resize

它和MATLAB一样吗?

2 个答案:

答案 0 :(得分:14)

是的,请注意MATLAB的imresizeanti-aliasing enabled by default

imresize(A,scale,'bilinear')

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

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

正如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;

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

请注意,结果与关闭抗锯齿的结果相同。

双立方差异

但是,在'bicubic'INTER_CUBIC之间,由于加权方案,结果会有所不同! See here了解数学差异的详细信息。问题出在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, 1, 2, 3;
  4, 5, 6, 7;
  8, 9, 10, 11;
  12, 13, 14, 15]
[2.1875, 4.3125;
  10.6875, 12.8125]

有关立方HERE的更多信息。

答案 1 :(得分:3)

在OpenCV中,调用将是:

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

然后你可能需要做一些平滑/模糊来模拟MATLAB默认执行的抗锯齿(参见@chappjc的回答)