gpt4 book ai didi

c++ - 二维卷积 - 与 opencv 输出相比的错误结果

转载 作者:行者123 更新时间:2023-11-28 06:26:45 27 4
gpt4 key购买 nike

我正在尝试实现一个简单的 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.我的实现):

1. image opencv, 2. my results

如果有人能解释我做错了什么,我将不胜感激。

最佳答案

对于初学者,您考虑边缘的条件应该使用 && 而不是 || ,如下所示:

if (x+n >= 0 && x+n <= image.cols && y+m >= 0 && y <= image.rows)

这应该有助于去除边缘周围的人工制品。

然后,对于内部区域的人工制品,您应该确保总和保持在 0-255 范围内,并尽量避免在每次将部分结果转换回 uint8_t 时失去分辨率当您分配给 sum 时:

float 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) = std::min(std::max(0.0f, sum), 255.0f);

关于c++ - 二维卷积 - 与 opencv 输出相比的错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28389273/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com