2D свертка — неверные результаты по сравнению с выводом opencv

Я пытаюсь реализовать простую двумерную свертку (средний фильтр в данном случае). Но когда я сравниваю свои результаты с изображением, сгенерированным opencv’s 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;
}

Результаты для размера ядра пять (1. opencv, 2. моя реализация):

1. изображение opencv, 2. мои результаты

Буду признателен, если кто-нибудь сможет объяснить мне, что я делаю не так.

0

Решение

Для начала, ваше условие для учета краев должно использовать && вместо || вот так:

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);
1

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector