Фильтр Собеля 3x3 получается путем умножения матрицы производного фильтра [-1 0 1] на фильтр сглаживания [1 2 1].Когда апертура становится 5x5, другое сглаживание применяется к обоим другим фильтрам.«Правильная» нормализация этих фильтров, то есть того, который заставляет их сложить до 1, должна быть 1/2 для производной и 1/4 для сглаживания.Таким образом, фильтр 3x3 должен быть нормализован на 1/8, 5x5 на 1/128 и 7x7 на 1/2048.Называя r диафрагмой, масштабирование должно быть:
.Более подробную информацию можно найти здесь .
Код для этого «должен»:
double scale = 1 << (2 * aperture_size - 3);
По какой-то причине я действительно не могу понять, OpenCV использует нормализацию
, что приводит к:
double scale = 1 << (aperture_size - 1);
Это означает, что масштабирование составляет 1/4 для 3x3, 1/16 для 5x5, 1/64 для 7x7.
Остальное легкопонять: если вы хотите использовать фильтр Scharr, диафрагма устанавливается на CV_SCHARR
, то есть -1 ( source ), поэтому условный оператор используется для установки диафрагмы на 3. Как ни странно,if
позже, который еще больше умножает все на 2, что могло бы быть включено в условный оператор, устанавливающий значение 4. Таким образом, нормализация для фильтра Шарра составляет 1/8.Опять же, я не знаю, почему.
Наконец, block_size
включается, но это легко понять: квадраты градиентов позже суммируются, то есть вы добавляете block_size*block_size
элементов.Чтобы их нормализовать, вы должны разделить на block_size*block_size
.Масштабирование на block_size
, а затем взятие квадрата делает свое дело.