MATLAB vs C++vs OpenCV-调整大小

MATLAB vs C++ vs OpenCV - imresize

本文关键字:调整 OpenCV- vs C++vs MATLAB      更新时间:2023-10-16

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

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

Gr = imresize(Gr, 1 / newScale);

在MATLAB文档中:

B=imresize(A,scale)返回的图像B是A.输入图像A可以是灰度、RGB或二进制图像。如果刻度在0和1.0之间,B小于A。如果刻度大于大于1.0,B大于A。

这意味着我将得到一个2D矩阵==矩阵宽度/2和矩阵高度/2
如何计算这些值?根据文档,默认值来自最近的4X4的三次插值。

我找不到能做同样事情的C++示例代码。你能提供这样一个代码的链接吗?

我还发现了这个OpenCV函数resize

它的作用和MATLAB的一样吗?

是的,只需注意MATLAB的imresize默认启用了抗锯齿功能:

imresize(A,scale,'bilinear')

与。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之间,由于加权方案的原因,结果不同!有关数学差异的详细信息,请参见此处。问题在于计算三次插值系数的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]

更多关于立方的信息,请点击此处。

在OpenCV中,调用为:

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

然后,您可能需要进行一些平滑/模糊来模拟MATLAB默认情况下也执行的抗锯齿(请参见@chappjc的答案)