Для функции cornerEigenValsVec
в corner.cpp, Я застрял на понимании влияния локальной переменной scale
переходя к Sobel
(от строки 257 до строки 263):
int depth = src.depth();
double scale = (double)(1 << ((aperture_size > 0 ? aperture_size : 3) - 1)) * block_size;
if( aperture_size < 0 )
scale *= 2.0;
if( depth == CV_8U )
scale *= 255.0;
scale = 1.0/scale;
Насколько я понимаю, масштаб будет 1/(255*12)
если src
имеет CV_8UC1
, Применение 1/255 нормализует интенсивность пикселей в [0,1]
, но как насчет дополнительного масштаба 1/12
? Каков его эффект?
Фильтр Собеля 3×3 получается путем умножения матрицы производного фильтра [-1 0 1] на фильтр сглаживания [1 2 1]. Когда апертура становится 5×5, другое сглаживание применяется к обоим другим фильтрам. «Правильная» нормализация этих фильтров, то есть та, которая заставляет их складывать до 1, должна быть 1/2 для производной и 1/4 для сглаживания. Таким образом, фильтр 3×3 должен быть нормализован на 1/8, 5×5 на 1/128 и 7×7 на 1/2048. призвание р апертура, масштабирование должно быть:
.
Более подробную информацию можно найти Вот.
Код для этого «должен»:
double scale = 1 << (2 * aperture_size - 3);
По какой-то причине я действительно не могу понять, OpenCV использует нормализацию , что приводит к:
double scale = 1 << (aperture_size - 1);
Это означает, что масштабирование составляет 1/4 для 3×3, 1/16 для 5×5, 1/64 для 7×7.
Остальное легко понять: если вы хотите использовать фильтр Scharr, диафрагма устанавливается на CV_SCHARR
то есть -1 (источник), поэтому условный оператор используется для установки диафрагмы на 3. Как ни странно, есть if
позже, который еще больше умножает все на 2, что могло бы быть включено в условный оператор, устанавливающий значение 4. Таким образом, нормализация для фильтра Шарра составляет 1/8. Опять не знаю почему.
Наконец то block_size
включается, но это легко понять: квадраты градиентов позже суммируются, то есть вы добавляете block_size*block_size
элементы. Чтобы их нормализовать, вы должны разделить на block_size*block_size
, Масштабирование по block_size
а затем взять квадрат делает свое дело.
Других решений пока нет …