Как стать автором
Обновить

Комментарии 24

Судя по заявленным целям, было бы уместнее сравнивать не с Гауссом, а медианой?
А вообще интересно.
Я бы сказал, что даже не с Гауссом, а с Bilateral.
Спасибо! На самом деле сравнивать так фильтры сложно, каждый выполняет свою задачу. Я привел для сравнения «на глаз» именно сглаживание Гаусса, потому что фильтр Перона-Малика по теории получается модификацией фильтра Гаусса (это на самом деле не совсем так, но когда функция c равняется единице, сглаживание фильтром анизотропной диффузии будет сходиться к гауссову сглаживанию).
Было бы интересно посмотреть, какой эффект дает последовательное применение этих алгоритмов. На взгляд дилетанта, они могут неплохо друг друга дополнять
http://gmic.eu/ тут огромное количество всяких продвинутых фильтров (анизотропное размытие точно есть) и минимально приличный интерфейс. Работает как плагин к GIMP
Спасибо за ссылку! Тут даже не просто фильтр Перона и Малика, а обобщенный для анизотропного размытия. У Перона и Малика ведь функция c — это скаляр, а вообще на месте функции c может стоять какой-то тензор. К тому же, если я правильно понял, плагин предлагает несколько вариантов дискретизации уравнения, что тоже не мало важно.
Это далеко не дилетантский взгляд, действительно — все зависит от задачи и исходных данных, особенно от типа шумов, ведь обычно их природа известна (хотя бы в теории). Вот, например, я сейчас занимаюсь обработкой изображений срезов керна (уже получены с томографа после обратного преобразования Радона) и там много шумов разной природы, даже больше скажу, некоторые «правильные» данные мы также трактуем как шумы, из-за их очень малой значимости для задачи в целом. Так вот, перед сегментацией мы фильтруем изображения кучей разных фильтров с различными параметрами, причем тут еще важен порядок.
P.S. Параметры мы настраиваем исходя из уже известных данных.
Я к тому, что если будете еще писать на подобные темы — было бы интересно почитать не только про сравнение, но и про совмещение разлиных методов :)
Хорошо, учту)

В качестве практической реализации на C++ семейства подобных фильтров, могу порекомендовать библиотеку ITK. В ней наиболее полная реализация этого алгоритма обобщённого для N-мерных данных. Есть также реализация на OpenCL.
https://itk.org/Doxygen/html/group__ITKAnisotropicSmoothing.html


А также дополнительный модуль Anisotropic Diffusion LBR:
https://github.com/InsightSoftwareConsortium/ITKAnisotropicDiffusionLBR
Публикация: http://insight-journal.org/browse/publication/953

А существует ли обобщение на случай полноцветных изображений? Вроде бы применение к каждому каналу независимо должно приводить к несовсем «корректному» (ожидаемому) результату.
Если честно, не слышал про обобщение. Но если принять, что функция изображения I — вектор-функция,
например I(x,y)=(r(x,y),g(x,y),b(x,y)), то из-за линейности операции дифференцирования для каждой координатной функции r,g,b будет записано свое уравнение анизотропной диффузии, поэтому, в целом, можно независимо по каналам считать. Правда, надо понимать, что при оценке границ в обычном фильтре мы используем градиент, и это просто вектор. А когда функция I — векторная, то градиент уже будет тензором, соответственно норма градиента будет другая и оценка этой нормы тоже. То есть поменяется расчет функции c. Если же применять в лоб алгоритм для каждого канала отдельно, то результат будет скорее всего «хуже», но все зависит от конкретной задачи.

Можно использовать цветовой градиент Di Zenzo, либо просто считать градиент по серому каналу.
Последнее будет даже лучше, потому что на практике практически не встречаются чисто цветовые градиенты.

Помимо уже упомянутой модификации фильтра можно преобразовать изображение в другое цветовое пространство вида "яркость + каналы цвета". Часто используют HSV, фотографы советуют более сложное но и лучше адаптированное к зрению LAB. Фильтр гоняют на яркостной компоненте, а цветовые хорошо ортогональны к ней и куда менее заметно влияют на результат, так что их вполне можно фильтровать независимо и более простыми фильтрами. Впрочем в медицине и прочих индустриальных применениях где нужны подобные фильтры интересующие нас данные почти всегда черно-белые.

А неявные схемы (чтобы увеличить шаг по времени — т.е. обсчитывать быстрее) пробовали? Или всё равно при увеличении Δt вылезает заметная погрешность, и выигрыша не получается (в смысле, ускорение за счёт доступного увеличения Δt "сжирается" усложнением схемы)?

Не пробовал, на это есть несколько причин. Во-первых, как вы уже заметили — сильно возрастает погрешность, то есть, в неявной схеме придется решать системы нелинейных уравнений (в зависимости от аппроксимации, в лучшем случае это может быть система многочленов), их тоже надо как-то аппроксимировать, отсюда — появляются дополнительные вычисление, возрастает невязка решения в целом. Во-вторых, решение, приведенное у меня в статье, легко распараллелить на вычислительном кластере, cpu и gpu.
Не пробовали ли Вы применять данный фильтр для сглаживания изображений текста перед OCR? Если да, то каковы результаты? Стоит ли пробовать вместо билатерального фильтра?

Ну вы же понимаете, что все от случая к случаю. Данный фильтр в фотошопе называется surface blur и присутствует там уже лет 8 точно.Можно сразу протестировать.

Да, я прекрасно это понимаю :)
Пробовал только ради интереса на одной картинке. Конечно, все зависит от конкретного алгоритма. Применять можно. Я взял исходное изображение из статьи Siarshai, прогнал через онлайновый файнридер результат анизотропной диффузии (t=15,k=14, функция g как у меня в реализации), результат билатерального фильтра (gmic online Spatial variance=3, Value variance=32, Iterations=6) и результат автора статьи. Ниже приведены исходное изображение, сглаженные и текст, распознанный файнридером. Ссылки на текст ведут на pastebin, изображения кликабельны.

Исходное:


Фильтр Перона и Малика (текст):


Билатеральный фильтр (текст):


Алгоритм предложенный Siarshai (текст):


Опять же повторюсь, что данные результаты не показатель качества работы фильтров.
Спасибо большое за проведённу работу.
"… некоторое размытие еще происходит, но начинают появляться артефакты." — это мы наблюдаем неустойчивость явной схемы. Сделайте шаги по времени раз в 100 помельче.
Ну и туда же. Судя по программе, вы аппроксимируете градиенты I в функции «с» или «g» направленными разностями. Пробовали использовать центральные разности?
Не совсем понимаю, зачем судить по программе, когда в разделе теории я написал по поводу аппроксимации. Норма градиента аппроксимируется длинной проекции градиента. Как я уже упоминал в статье, Перона и Малик предложили такую аппроксимацию, хотя она и не совсем соответствует исходному уравнению, потому что она достаточно «дешевая» в плане вычислений и использование более точных аппроксимаций качественно не меняет общий результат. Кстати, изначально я как раз через центральные разности делал, разницы практически никакой не было, по крайней мере для алгоритма сегментации.

Что касается вашего замечания о неустойчивости, вы, наверное, просто не заметили сверху над изображением такую строчку: «Теперь попробуем нарушить условие устойчивости». Что касается устойчивости, то как я уже писал в разделе теории, условие следующее: .
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации