我有以下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一样吗?
答案 0 :(得分:14)
是的,请注意MATLAB的imresize
有anti-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的回答)