我试图使用OpenCV将MATLAB代码翻译成C ++。特别是,我正在尝试翻译以下功能:
function sigma = EstimateNoise(inputImg)
[h, w]=size(inputImg);
inputImg = double(inputImg);
% compute sum of absolute values of Laplacian
M = [1 -2 1; -2 4 -2; 1 -2 1];
sigma = sum(sum(abs(conv2(inputImg, M))));
% scale sigma with proposed coefficients
sigma = sigma*sqrt(0.5*pi)./(6*(w-2)*(h-2));
end
我的模拟
double EstimateNoise(Mat inputImg) {
int width = inputImg.cols;
int height = inputImg.rows;
// compute sum of absolute values of Laplacian
char M[9] = {1,-2,1 -2,4,-2, 1,-2,1};
Mat MatM = Mat(3, 3, CV_8S, M);
filter2D(inputImg, inputImg, inputImg.depth(), MatM);
//conv2(inputImg, MatM, CONVOLUTION_FULL, inputImg);
absdiff(inputImg, Scalar::all(0), inputImg);
Scalar summa = sum(inputImg);
double sigma = summa[0];
// scale sigma with proposed coefficients
sigma = sigma*sqrt(0.5*M_PI) / (6 * (width - 2)*(height - 2));
return sigma;
}
但是这些函数的结果差异很大(在C ++中约为3.15,而在~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我在网络上找到了改进的conv2
版本,其中包含其他参数'same'
和'valid'
,其结果与内置filter2D
差别不大。
这个功能本身:
void conv2(const Mat &img, const Mat& kernel, \
ConvolutionType type, Mat& dest) {
Mat source = img;
if (CONVOLUTION_FULL == type) {
source = Mat();
const int additionalRows = kernel.rows - 1, additionalCols = kernel.cols - 1;
copyMakeBorder(img, source, (additionalRows + 1) / 2, additionalRows / 2, \
(additionalCols + 1) / 2, additionalCols / 2, \
BORDER_CONSTANT, Scalar(0));
}
Point anchor(kernel.cols - kernel.cols / 2 - 1, \
kernel.rows - kernel.rows / 2 - 1);
int borderMode = BORDER_CONSTANT;
flip(kernel, kernel, -1);
filter2D(source, dest, img.depth(), kernel, anchor, 0, borderMode);
if (CONVOLUTION_VALID == type) {
dest = dest.colRange((kernel.cols - 1) / 2, dest.cols - kernel.cols / 2)
.rowRange((kernel.rows - 1) / 2, dest.rows - kernel.rows / 2);
}
}
您对获得类似于MATLAB的结果有何建议?