Перейти к содержимому
Compvision.ru
mrgloom

Свертка (convolution)

Recommended Posts

сам процесс в дискретном случае понятен(т.е. просто проходим окном по всему изображению и т.д.), но как выбирают значения для ячеек ядра?

может есть какая то теория по этому поводу?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вот слайды, которые я переводил для лекций:Выделение границ.pdf

это только один из возможных случаев применения свертки, однако принцип перехода от непрерывной модели к дискретной должен быть из слайдов понятен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ну вообщем получается, что свертка это просто отдельная математическая операция, которая в дискретном случае так реализуется.

хотя там все таки не очень понятно откуда взяли матрицу 5х5(оператор собеля)?

и еще от дифференцирования в дискретном случае там сразу переход к ядру свертки, тоже не очень понятно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну тут просто: к якорю Iij прибавляются значения пикселей, находящихся под клетками ядра свертки, умноженные на содержимое клетки ядра свертки. Получается суммирование с весами. Результат заносится в другое изображение в координату якоря (ij).

post-1-0-31011700-1312813338_thumb.png

post-1-0-57193300-1312813431_thumb.png

Вот тут еще очень неплохая статья: http://ktf.oleg29.ru/courses/fulleren/g3.htm

ЗЫ: По поводу собеля, по ядру видно, что учитываются 2 ряда пикселей с каждой стороны, если мы имеем дело с производной, то чем больше расстояние между пикселями, тем больше будет разница значений яркостей при том же градиенте, поэтому коэффициенты убывают к периферии

(F'=dI/dx) производная как бы "размазывается".

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Ну тут просто: к якорю Iij прибавляются значения пикселей, находящихся под клетками ядра свертки, умноженные на содержимое клетки ядра свертки. Получается суммирование с весами. Результат заносится в другое изображение в координату якоря (ij).

это то я знаю, просто я не особо понимаю, что такое сама свертка.(википедию почитал, но видимо надо почитать матан и еще про фурье анализ)

ЗЫ: По поводу собеля, по ядру видно, что учитываются 2 ряда пикселей с каждой стороны, если мы имеем дело с производной, то чем больше расстояние между пикселями, тем больше будет разница значений яркостей при том же градиенте, поэтому коэффициенты убывают к периферии

(F'=dI/dx) производная как бы "размазывается".

это из общих соображений тоже понятно, но непонятно как получаются сами значения в матрице.

т.е. например есть у нас формура свертки y=h*f ,где h-ядро, непонятно какой мы смысл вкладываем в h -функция,оператор или что еще?

и каким способом в общем случае переводим h в дискретное представление?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Свертка это просто удобный оператор. Никакой излишней магией его наделять не нужно. Фурье-анализ Вам понадобится если будете работать в частотном пространстве (frequency domain). Но все что можно сделать сверткой делается и обычными "человекопонятными" операциями. Просто сверткой быстрее и компактнее.

По поводу производных: http://en.wikipedia.org/wiki/Finite_difference

в операторе Собеля используется центральная разность и у меня такое подозрение что наложенная на гауссиан, увеличивающий значение точек, находящихся ближе к середине и ослабляющий периферийные точки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

дело в том, что оператор собеля как раз, как я понял,следует из finite difference approximation производной и не очень понятно как можно увеличивать размер ядра в таком случае.

а например гауссиана это просто функция, но из нее тоже как то получают ядро.

получается можно получить ядро из любой функции?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

размер ядра увеличивается так: считаем df1=dI1/dx1 где df1 - производная, dI1 - разница яркостей, dx1 - расстояние между точками. Затем считаем df2=dI2/dx2 увеличив расстояние между точками, но при этом увеличится и разность яркостей.

Для линейного градиента df1=df2, для нелинейного, усредняется.

По поводу Гауссиана, мне сложно объяснить по простому :) но там тоже взвешенная сумма соседей точки-якоря. Можно сделать ядро для любой функции (функция при этом будет задавать веса точек-соседей).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

у меня не очень укладывается все таки операция взятия производной и (произвольная)функция это вроде как разные вещи.

+ получается через свертку можно представить только линейные фильтры?

correlation is in principle the same operation as linear convolution

вот что еще вычитал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

опять же возвращаясь к теме ядер, как получить ядро для лапласиана большего размера?

или ж еего впринципе не меняют, а делают пирамиду из изображений?

Laplacian kernel size

0 -1 0

-1 4 -1

0 -1 0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

http://stackoverflow.com/questions/8070586/bigger-mask-size-for-laplacian-filter

что то я не понимаю как из того что выдала математика получить

0 -1 0

-1 4 -1

0 -1 0

т.е. по какому правилу делается сама аппроксимация?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

У Гонсалеса и Вудса так:

L=d2f/dx2+d2f/dy2;

d2f/dx2=f(x+1,y)+f(x-1,y)-2f(x,y);

d2f/dy2=f(x,y+1)+f(x,y-1)-2f(x,y);

L = d2f/dx2+d2f/dy2 = f(x+1,y)+f(x-1,y) + f(x,y+1)+f(x,y-1) - 4f(x,y);

Получается инверсия, но это не особо важно.

Есть еще вариант, учитывающий диагонали, там ядро представляет собой 8 окруженную -1 (или -8 окруженную 1).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

L=d2f/dx2+d2f/dy2;

d2f/dx2=f(x+1,y)+f(x-1,y)-2f(x,y);

d2f/dy2=f(x,y+1)+f(x,y-1)-2f(x,y);

L = d2f/dx2+d2f/dy2 = f(x+1,y)+f(x-1,y) + f(x,y+1)+f(x,y-1) - 4f(x,y);

это же получается опять же ядро 3х3? например тоже ядро гауссианы может быть больше чем 3х3,т.е. тут используется какая то дискретная аппроксимация(причем еще непонятно могут ли быть у ядра фильтра не int значения?)

кстати еще про связь кореляции и конволюции

http://dsp.stackexchange.com/questions/2654/what-is-the-difference-between-convolution-and-cross-correlation

но я что то математический смысл этих операций как то не улавливаю(хотя может быть его и нет).

http://www.cs.umd.edu/~djacobs/CMSC426/Convolution.pdf

еще тут описывается свзять евклидовой метрики с кореляцией и зачем надо нормировать и еще опять же про взятие производной(через конволюцию).

а потом там еще пишут что кореляция это скалярное произведение(Correlation as an inner product).

и еще

Without the conjugation, it computed convolution instead of correlation.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Соорудил GPU-шное размытие гауссианом с произвольной дисперсией, посредством DFT.

Вот что получилось для дисперсии равной 100:

post-1-0-94803300-1355336740_thumb.jpg

исходник тут:

DFT_Gaussian_GPU.cpp

Кстати, если задать дисперсию небольшим отрицательным значением, например равной -0.5, то изображение становится резче:

post-1-0-93680000-1355338157_thumb.jpg

post-1-0-55830700-1355338566_thumb.jpg

Скорострельность у меня очень близка к реалтайм (немного заметно притормаживание).

Исходник работающий с камерой:

DFT_Gaussian_GPU_cam.cpp

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

лучше бы сюда запостили

http://www.compvision.ru/forum/index.php?showtopic=110

я по коду не понял мы делаем гауссиану размером с изображение и перемножаем с изображением в частотной области?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну это все таки свертка :), соорудил эту функцию из-за того что у opencv-шной GPU-шной реализации ограничение по размеру ядра всего 31х31.

Да, делаем гауссиан, в частотной области и перемножаем спектры.

Только есть, как минимум, три разных варианта гауссовых фильтров:

низкочастотный - ослабляет по гауссу высокие частоты (чем больше дисперсия, тем меньше размытие), фактически, дисперсия - это частота среза фильтра;

высокочастотный (здесь чем больше дисперсия, тем больше низких частот срезается), здесь тоже дисперсия, это частота среза фильтра;

и такой как этот, деиствие которого аналогично свертке гауссовым ядром (больше дисперсия - больше размытие).

Делал по статье из вики:

http://en.wikipedia.org/wiki/Discrete_Gaussian_kernel#The_discrete_Gaussian_kernel

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ну всё таки с FFT.

непонятно почему делаем гауссиан размеров со всё изображение?

и почему перед перемножением не переводим в частотную область?

таким же образом можно делать ядро любого размера и в пространсвенной области?

Только есть, как минимум, три разных варианта гауссовых фильтров:

низкочастотный - ослабляет по гауссу высокие частоты (чем больше дисперсия, тем меньше размытие), фактически, дисперсия - это частота среза фильтра;

высокочастотный (здесь чем больше дисперсия, тем больше низких частот срезается), здесь тоже дисперсия, это частота среза фильтра;

и такой как этот, деиствие которого аналогично свертке гауссовым ядром (больше дисперсия - больше размытие).

что то это всё только запутало. Формула одна но применяется как то поразному?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Для фильтра чем больше ядро, тем качественнее результат, лучше всего вообще бесконечное, но это нереально.

При фильтрации гауссианом, важно значение дисперсии.

При малых значениях дисперсии размер ядра может быть небольшим, т.к. значения коэффициентов на периферии ядра имеют маленькие значения и мы можем их отсечь почти без ущерба для качества фильтрации.

При больших значениях, ядро убывает медленно, и уменьшая ядро мы искажаем результат фильтрации, отсекая часть с существенными значениями коэффициентов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

http://www.cs.ioc.ee/~khoros2/linear/convolution-teo/front-page.html

вот тут еще про эквивалентность операций в spatial and frequency domain.

непонятно как получают extended convolution kernel.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

опять возвращаясь к этой не очень ясной с математической точки зрения теме.

http://en.wikipedia.org/wiki/Discrete_Laplace_operator

вот например тут про дискретный оператор лапласа. (Discrete Laplace operator)

Раздел Finite Differences

Approximations of the Laplacian, obtained by the finite difference method or by the finite element method can also be called Discrete Laplacians. For example, the Laplacian in two dimensions can be approximated using the five-point stencil finite difference method

и опять же сразу такой переход

Implementation in Image Processing

For one, two and three dimensional signals, the discrete Laplacian can be given as convolution with the following kernels

т.е. как мы оператор как то выражаем помощью конволюции.

хочется уже даже спросить что такое "оператор" с математической точки зрения и любой ли оператор можно выразить с помощью конволюции в дискретном случае.

опять же например гауссиана это просто функция, но из нее тоже как то получают ядро.

получается можно получить ядро из любой функции? функция!=оператор?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Сверткой можно реализовать только линейные операторы.

То есть те, которые представимы в виде линейной комбинации соседних пикселей (если для изображения).

Если оператор удается линеаризовать, как это сделано для Лаплассиана и Гауссиана, то его можно реализовать в виде свертки.

Я не очень силен в математической терминологии, но насколько я понимаю, понятие оператора шире понятия функции.

Оператор я бы определил как вообще любое действие производимое с операндом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

http://ru.wikipedia.org/wiki/Алгоритм

Советую прочитать формальное определение алгоритма.

функция!=оператор?

Да, это разные понятия. В математическом смысле функция она шире оператора. Что касается не математического, то не знаю.

Если верить википедии, то не любой. Но большинство будут исчислимы.

опять же например гауссиана это просто функция, но из нее тоже как то получают ядро.

получается можно получить ядро из любой функции?

Я бы не сказал что из функции получают ядро. Её просто используют как ядро.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хорошее описание с анимацией: http://mathworld.wolfram.com/Convolution.html

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×