问题描述
我有下面的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);
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!