свертка
[-3 -5 0 5 3] * A
является своего рода приближением к фактической производной . Поскольку A
является выборкой, мы не можем знать истинную производную. Нам нужно дискретное приближение. Одним из распространенных подходов является метод конечных разностей , где просто принимают разницу между последующими элементами: A[x+1,y]-A[x,y]
. Это то, что вы получите, заполнив производное предельное уравнение в дискретном случае. Lim h->0
становится h=1
, интервал не меньше. Эта разница может быть вычислена с использованием свертки:
[1 -1] * A
Эта операция возвращает производную в месте между двумя пикселями. Чтобы преодолеть это, можно использовать центральную разницу: (A[x+1,y]-A[x-1,y])/2
или в форме свертки:
[1/2 0 -1/2] * A
Дальнейшие улучшения можно получить, свернув с производной гауссиана . Гауссово является своего рода оптимальным, когда речь идет о сглаживающих (регуляризационных) фильтрах Кроме того, свертка имеет свойство: d/dx (A * G) = A * d/dx G
. Таким образом, свертка изображения с производной гауссианы аналогична производной true изображения, сглаженного гауссианой. Вы можете написать такую 1D свёртку как:
[0.013 0.108 0.242 0.0 -0.242 -0.108 -0.013] * A
Обратите внимание, что было бы лучше также свертывать столбцы с гауссианом, чтобы сохранить вещи изотропными. Но давайте пока проигнорируем это.
По какой-то причине люди в сообществе Computer Vision, похоже, испытывают аллергию на значения с плавающей точкой (в последнее время это значительно улучшается, но всегда найдутся люди, которые думают, что дешевле вычислять сверточные числа с целочисленными значениями). Таким образом, кажется, что на странице, на которую вы ссылались, они заменили фактическую производную ядра Гаусса на целочисленное ядро, которое приближается к нему. Это приводит к [3 5 0 -5 -3]
. Им также удалось инвертировать значения, что привело к операции, которая приблизительно равна -d/dx
.
То, что они позже используют Габора для определения ориентации, показывает далее, что они на самом деле не знают, что делают, поскольку Габор является более плохим приближением к истинному градиенту, чем то, что вы можете сделать с производными Гаусса.
Короче говоря, если вы хотите вычислить производные, сделайте следующее:
A * d/dx G(x) * G(y)
(с G(x)
1D гауссианом как функцией x
, то есть горизонтальным вектором, и G(y)
его транспонированием; и дискретизацией d/dx G(x)
напрямую, а не выборкой G(x)
и вычислением его конечной разностной производной) .
Чтобы вычислить производную по оси y
, сделайте то же самое, но с производной ядра G(y)
.
Практические советы по внедрению зависят от вашего языка. Вот несколько советов по использованию MATLAB . Это, вероятно, хорошо переводится и на другие языки.
Относительно строки сканирования 5x5: я не знаю, что это значит. Я думаю, что они каким-то образом пробуют изображение для повышения производительности. Меньше пикселей = быстрее вычисление.