【问题标题】:Make OpenCV resize do the same as Matlab/Octave imresize使 OpenCV 调整大小与 Matlab/Octave imresize 相同
【发布时间】:2018-11-10 12:03:08
【问题描述】:

我目前正在将一些代码从 Matlab 移植到 C++,并且在调整图像大小时遇到​​了一些困难。我正在使用 OpenCV 在 C++ 中调整大小,但结果不匹配。我知道 Matlab 中的抗锯齿选项,但在这种情况下,我正在扩大规模,因此 Matlab 不使用该选项。

Matlab 代码:

imresize(a,1.3, 'bilinear')

C++ 代码:

double scale = 1.3;
cv::Mat a = (cv::Mat_<double>(5, 5) << 0.7430835, 0.2263354, 0.8372651, 0.4305077, 0.0060997,
                                       0.1850839, 0.4359681, 0.6224524, 0.3951009, 0.3335419,
                                       0.5295836, 0.0202813, 0.8555994, 0.3494351, 0.6370482,
                                       0.3154180, 0.4335316, 0.6281235, 0.3844186, 0.9898034,
                                       0.9576555, 0.0212430, 0.3106115, 0.2677145, 0.1495867);
cv::Mat b;
cv::Mat c;

cv::resize(a, b, cv::Size(), scale, scale, CV_INTER_LINEAR);

cv::resize(a, c, cv::Size(ceil(scale * 5), ceil(scale * 5)), 0, 0, CV_INTER_LINEAR);

我注意到矩阵 b 给了我错误的尺寸,所以在 c 中我指定了尺寸而不是比例因子。即使尺寸正确,它也不会提供相同的结果:

Matlab:

a=
0.7430835   0.2263354   0.8372651   0.4305077   0.0060997
0.1850839   0.4359681   0.6224524   0.3951009   0.3335419
0.5295836   0.0202813   0.8555994   0.3494351   0.6370482
0.3154180   0.4335316   0.6281235   0.3844186   0.9898034
0.9576555   0.0212430   0.3106115   0.2677145   0.1495867

ans =
0.7430835   0.3985848   0.4299787   0.8372651   0.5660935   0.2890383   0.0060997
0.3710838   0.3677549   0.4754126   0.6940566   0.5026210   0.3460670   0.2243945
0.2999171   0.2982429   0.4316599   0.7001681   0.4866420   0.3981562   0.4347107
0.5295836   0.1900488   0.2987207   0.8555994   0.5181565   0.4453061   0.6370482
0.3868066   0.3261232   0.4318373   0.7039488   0.4831546   0.5392444   0.8722183
0.5294972   0.3739004   0.3714968   0.5222862   0.4044402   0.4669219   0.7097312
0.9576555   0.3333805   0.1176992   0.3106115   0.2820135   0.2283386   0.1495867

C++:

a:
0.743084 0.226335 0.837265 0.430508 0.0060997
0.185084 0.435968 0.622452 0.395101 0.333542
0.529584 0.0202813 0.855599 0.349435 0.637048
0.315418 0.433532 0.628123 0.384419 0.989803
0.957655 0.021243 0.310611 0.267715 0.149587

b:
0.743084 0.40521 0.484806 0.759043 0.446152 0.120363
0.378238 0.368538 0.50446 0.641146 0.41849 0.270586
0.330834 0.284585 0.455135 0.654686 0.389062 0.438749
0.488398 0.234284 0.401026 0.724221 0.373689 0.610999
0.323655 0.385105 0.510391 0.588065 0.392835 0.816538
0.784745 0.35811 0.243873 0.377449 0.302864 0.355159

c:
0.743084 0.447799 0.400887 0.837265 0.546724 0.248619 0.0060997
0.424227 0.379597 0.45138 0.714515 0.497201 0.317247 0.19321
0.283512 0.302763 0.423448 0.689066 0.469771 0.398427 0.420258
0.529584 0.238554 0.258944 0.855599 0.494054 0.472698 0.637048
0.376608 0.341666 0.423362 0.693117 0.465479 0.594963 0.889016
0.590663 0.399905 0.324039 0.492047 0.379444 0.460963 0.62971
0.957655 0.422563 0.10392 0.310612 0.279971 0.217088 0.149587

很遗憾,我无法编辑 Matlab 代码,因此所有更改都需要在 C++ 中完成。有谁知道如何让 OpenCV 提供与 Matlab 相同的结果,还是我需要创建自己的函数?

最好的问候 桑德雷

相关的 SO 问题:

MATLAB vs C++ vs OpenCV - imresize

why OpenCV cv2.resize gives different answer than MATLAB imresize?

imresize bilinear MATLAB

【问题讨论】:

  • 对我来说这看起来很重要。区别一定在于 OpenCV 和 Matlab 使用的线性插值方法。这可能会非常耗时,但您可以查看modules/imgproc/src/resize.cpp:4037 中的 OpenCV 实现(它后来委托给 hal::resize),imresize.m 文件中当然提供了 matlab 实现。

标签: c++ matlab opencv octave image-resizing


【解决方案1】:

cv::resizeimresize 之间有一个重要区别。重要的是要注意

>> imresize(a, 1.3, 'bilinear')

ans =

    0.7431    0.4052    0.4848    0.7590    0.4462    0.1204    0.0061
    0.3782    0.3685    0.5045    0.6411    0.4185    0.2706    0.2202
    0.3308    0.2846    0.4551    0.6547    0.3891    0.4387    0.4619
    0.4884    0.2343    0.4010    0.7242    0.3737    0.6110    0.7049
    0.3237    0.3851    0.5104    0.5881    0.3928    0.8165    0.9762
    0.7847    0.3581    0.2439    0.3774    0.3029    0.3552    0.3758
    0.9577    0.3454    0.1437    0.3024    0.2694    0.1814    0.1496

>> imresize(a, ceil(size(a)*1.3), 'bilinear')

ans =

    0.7431    0.4478    0.4009    0.8373    0.5467    0.2486    0.0061
    0.4242    0.3796    0.4514    0.7145    0.4972    0.3172    0.1932
    0.2835    0.3028    0.4234    0.6891    0.4698    0.3984    0.4203
    0.5296    0.2386    0.2589    0.8556    0.4941    0.4727    0.6370
    0.3766    0.3417    0.4234    0.6931    0.4655    0.5950    0.8890
    0.5907    0.3999    0.3240    0.4920    0.3794    0.4610    0.6297
    0.9577    0.4226    0.1039    0.3106    0.2800    0.2171    0.1496

不要产生相同的结果。在第一种情况下,图像真正缩放了1.3 的因子,而在第二种情况下,缩放是由 MATLAB 推导出的,在这种情况下为5/3=1.6666。这可以理解如下:如果我们为 MATLAB 函数imresize 提供比例因子,则图像将使用该因子进行缩放,并推导出调整后图像的大小(使用ceil)。如果我们将尺寸提供给imresize MATLAB 使用这些尺寸来推断比例,因此我们最终会得到不同的结果。

另一方面,如果仅提供比例因子(fxfy),OpenCV 使用 round 来推断调整后的图像大小。根据 OpenCV 的documentation,应该可以同时提供dsizefxfy,并实现与 MATLAB 中类似的行为。不幸的是,如resize: cannot specify both size and fx/fy中所述,文档似乎是错误的

因此,如果不更改 OpenCV 源代码,我们无法将 MATLAB 的行为与 OpenCV 完全匹配。

【讨论】:

    【解决方案2】:
    height, width = img.shape[:2]
    res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)
    

    缩放只是调整图像的大小。为此,OpenCV 附带了一个函数 cv.resize()。图像的大小可以手动指定,也可以指定缩放因子。假设您已读取 img 变量中的图像。这是用python编写的。希望这会有所帮助

    【讨论】:

      猜你喜欢
      • 2021-09-19
      • 2015-03-07
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 2014-03-26
      • 2016-02-08
      • 1970-01-01
      相关资源
      最近更新 更多