Размер ядра opencv gaussianblur 0

Как указано в документы opencv,

ksize – Gaussian kernel size. ksize.width and ksize.height can differ but they both must be positive and odd. Or, they can be zero’s and then they are computed from sigma* .

Я попытался установить размер ядра равным 0:

Mat input = imread(inputImagePath, IMREAD_COLOR);
Mat smooth;
int sigma=1;
GaussianBlur(input, smooth, Size(0, 0), sigma);

В результате:

OpenCV(3.4.1) Error: Assertion failed (ksize.width > 0 && ksize.width % 2 == 1 && ksize.height > 0 && ksize.height % 2 == 1) in createGaussianKernels

Работает с Size(3, 3). Где я не прав? Спасибо.

Основываясь на исходной ссылке на документацию ... вы используете OpenCV 3.4.1, но обратитесь к документации для 2.4.x - имейте в виду, что в API были внесены некоторые небольшие изменения, поэтому рекомендуется ссылаться на те, которые соответствовать используемой вами версии. Однако, насколько я могу судить, это не похоже на источник проблемы.

Dan Mašek 11.04.2018 16:01

Как вы выяснили, что документация для 2.4? По ссылке 3.4: docs.opencv.org/3.4.1/d4/d86/…

Gerry 11.04.2018 16:31

Потому что я прочитал это перед тем, как одобрить правку Дмитрия. | Кстати, можете ли вы попробовать это с какой-нибудь более старой версией OpenCV? До сих пор я пытался воспроизвести его с помощью 3.1.0, которая была у меня под рукой, но не смог. Это может быть регресс или какое-то недавнее изменение, которое не вошло в документацию. Я интерпретирую документацию так же, как и вы, и это должно работать (если я тоже чего-то не упускаю: D).

Dan Mašek 11.04.2018 16:35

Судя по виду исходный код, код Джерри должен работать. Может быть, нестабильная сборка? Попробуйте установить opencv из стабильного канала

Dmitrii Z. 11.04.2018 16:45

@DmitriiZ. Да, я это тоже просто просматривал, что часть не изменилась за 8 лет ... Довольно странно.

Dan Mašek 11.04.2018 16:49
0
5
973
2

Ответы 2

Вы не можете сделать размер ядра нулевым. Вы можете сделать значения сигмы равными нулю. Вот почему утверждение не удалось.

Также важно отметить, что размеры ядра должны быть строго нечетными.

Вы можете вызвать cv::GaussianBlur(...) с вашим ядром, в этом случае размер ядра в обоих измерениях должен быть странный: kernel.width % 2 == 1 && kernel.height % 2 == 1.

Или вы можете оставить размер ядра не установленным и указать положительные значения сигмы (sigma1 должен быть установлен, sigma2 будет установлен равным ему по умолчанию). Если это так, ядро ​​вычисляется следующим образом:

template <typename T>
static void createGaussianKernels( T & kx, T & ky, int type, Size &ksize,
                               double sigma1, double sigma2 )
{
int depth = CV_MAT_DEPTH(type);
if( sigma2 <= 0 )
    sigma2 = sigma1;

// automatic detection of kernel size from sigma
if( ksize.width <= 0 && sigma1 > 0 )
    ksize.width = cvRound(sigma1*(depth == CV_8U ? 3 : 4)*2 + 1)|1;
if( ksize.height <= 0 && sigma2 > 0 )
    ksize.height = cvRound(sigma2*(depth == CV_8U ? 3 : 4)*2 + 1)|1;

CV_Assert( ksize.width  > 0 && ksize.width  % 2 == 1 &&
           ksize.height > 0 && ksize.height % 2 == 1 );
...
...
}

Это из источников OpenCV 4.1.1. Итак, ваш код выглядит вполне корректным. Я скомпилировал его, и он работал без утверждения, как и ожидалось. Проверьте, какую версию библиотеки вы используете, но это самый базовый функционал, который в последнее время практически не менялся.

Вы также можете попробовать предоставить как sigma1, так и sigma2 (и использовать двойные значения, чтобы избежать неявного преобразования типов):

double sigmaX = 1.;
double sigmaY = 1.;
cv::GaussianBlur(input, smooth, cv::Size(0, 0), sigmaX, sigmaY);

Другие вопросы по теме