【发布时间】:2015-02-08 00:43:43
【问题描述】:
我正在尝试实现一个简单的 2D 卷积(在这种情况下为均值滤波器)。但是当我将我的结果与 opencv 的 filter2D 函数生成的图像进行比较时,我发现了很多差异。我当前的代码是:
cv::Mat filter2D(cv::Mat& image, uint32_t kernelSize = 3)
{
float divider = kernelSize*kernelSize;
cv::Mat kernel = cv::Mat::ones(kernelSize,kernelSize,CV_32F) / divider;
int kHalf = kernelSize/2.f;
cv::Mat smoothedImage = cv::Mat::ones(image.rows,image.cols,image.type());
for (int32_t y = 0; y<image.rows; ++y) {
for (int32_t x = 0; x<image.cols; ++x) {
uint8_t sum = 0;
for (int m = -kHalf; m <= kHalf; ++m) {
for (int n = -kHalf; n <= kHalf; ++n) {
if (x+n >= 0 || x+n <= image.cols || y+m >= 0 || y <= image.rows) {
sum += kernel.at<float>(m+kHalf, n+kHalf)*image.at<uint8_t>(y-m+1, x-n+1);
} else {
// Zero padding - nothing to do
}
}
}
smoothedImage.at<uint8_t>(y,x) = sum;
}
}
return smoothedImage;
}
内核大小为 5 的结果是(1.opencv,2.我的实现):
如果有人能解释我做错了什么,我将不胜感激。
【问题讨论】:
-
您可能应该在您的
if中使用&&而不是||。 -
对我来说似乎是合理的,但这并不影响内部图像区域中缺失的细节和伪影。
-
伪影很可能是由于过饱和造成的。尝试限制值的范围,使其不超过 uint8_t (255) 的最大值。此外,每次将部分结果转换为
uint8_t到sum时,您可能都会失去分辨率。考虑用浮点数计算总和,并限制结果。 -
这正是解决方案。感谢您指出这一点。
标签: c++ opencv convolution