Нужно больше разных Blur-ов

в 16:12, , рубрики: Blur, wolfram mathematica, математика, обработка изображений, размытие

Размытие изображение посредством фильтра Gaussian Blur широко используется в самых разных задачах. Но иногда хочется чуть большего разнообразия, чем просто один фильтр на все случаи жизни, в котором регулировке поддаётся только один параметр — его размер. В этой статье мы рассмотрим несколько других реализаций размытия.

Нужно больше разных Blur-ов - 1

Введение

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

Фильтр называется Gaussian, потому что он строится из функции, известной как гауссиана, $e^{-x^2}$:

Нужно больше разных Blur-ов - 3

двумерный вариант которой получен её вращением относительно оси ординат, $e^{-(x^2+y^2)}$:

Нужно больше разных Blur-ов - 5

Здесь для каждой пары координат $(x,y)$ рассчитывается расстояние до центра по формуле $sqrt{x^2+y^2}$, которое передаётся как аргумент в функцию гауссианы.

Матрица, построенная на отрезке $[-3,3]$ и с некоторым уровнем дискретизации, будет выглядеть так:

$left( begin{array}{ccccccc} 1.52 times 10^{-8} & 2.26 times 10^{-6} & 0.0000454 & 0.000123 & 0.0000454 & 2.26 times 10^{-6} & 1.52 times 10^{-8} \ 2.26 times 10^{-6} & 0.000335 & 0.00674 & 0.0183 & 0.00674 & 0.000335 &2.26 times 10^{-6} \ 0.0000454 & 0.00674 & 0.135 & 0.368 & 0.135 & 0.00674 & 0.0000454 \ 0.000123 & 0.0183 & 0.368 & 1.00 & 0.368 & 0.0183 & 0.000123 \ 0.0000454 & 0.00674 & 0.135 & 0.368 & 0.135 & 0.00674 & 0.0000454 \ 2.26 times 10^{-6} & 0.000335 & 0.00674 & 0.0183 & 0.00674 & 0.000335 &2.26 times 10^{-6} \ 1.52 times 10^{-8} & 2.26 times 10^{-6} & 0.0000454 & 0.000123 & 0.0000454 & 2.26 times 10^{-6} & 1.52 times 10^{-8} \ end{array} right) $

Или, если рассматривать значения элементов матрицы как уровень яркости, так:

Нужно больше разных Blur-ов - 10

что в терминах обработки сигналов называется импульсной характеристикой, поскольку именно так будет выглядеть результат свёртки данного фильтра с единичным импульсом (в данном случае — пикселем).

Изначально гауссиана определена на бесконечном интервале. Но за счёт того, что она довольно быстро затухает, можно исключить из вычислений значения, близкие к нулю — поскольку они всё равно не отразятся на результате. В реальных приложениях также необходима нормализация по значению, чтобы после свёртки яркость изображения не изменялась; а в случае размытия изображения, в котором каждый пиксель имеет один и тот же цвет, не должно меняться и само изображение.

Для удобства часто используют нормализацию и по координатам, посредством введения дополнительного параметра $sigma$ — чтобы рассматривать аргумент в диапазоне $[-1,1]$, а $sigma$ определяет степень сжатия гауссианы:

$frac{e^{-frac{x^2+y^2}{2 sigma ^2}}}{2 pi sigma ^2}$

Делитель $2 pi sigma ^2$ здесь получен через определённый интеграл на бесконечности:

$int_{-infty }^{infty } int_{-infty }^{infty } e^{-frac{x^2+y^2}{2 sigma ^2}} , dx dy=2 pi sigma ^2$

Начало

Для произвольного фильтра нам нужно сначала определить собственную функцию затухания от одной переменной $f$, из которой вращением получается функция от двух переменных путём замены $x$ на $sqrt{x^2+y^2}$, где $x$ и $y$ это координаты элемента матрицы в диапазоне $(-1,1)$, и которая далее используется для заполнения элементов матрицы. Нормализацию будем считать не аналитически, а непосредственным суммированием всех элементов матрицы — это и проще, и точнее — поскольку после дискретизации функция получается «прореженной», и значение нормализации будет зависеть от уровня дискретизации.

В случае, если элементы матрицы нумеруются с нуля, координата $x$ или $y$ считается по формуле

$frac{2 index}{size-1}-1$

где $index$ — порядковый номер элемента в строке или столбце, а $size$ — общее количество элементов.

Например, для матрицы 5 на 5 это будет выглядеть так:

$left( begin{array}{ccccc} f(-1,-1) & fleft(-frac{1}{2},-1right) & f(0,-1) & fleft(frac{1}{2},-1right) & f(1,-1) \ fleft(-1,-frac{1}{2}right) & fleft(-frac{1}{2},-frac{1}{2}right) & fleft(0,-frac{1}{2}right) & fleft(frac{1}{2},-frac{1}{2}right) & fleft(1,-frac{1}{2}right) \ f(-1,0) & fleft(-frac{1}{2},0right) & f(0,0) & fleft(frac{1}{2},0right) & f(1,0) \ fleft(-1,frac{1}{2}right) & fleft(-frac{1}{2},frac{1}{2}right) & fleft(0,frac{1}{2}right) & fleft(frac{1}{2},frac{1}{2}right) & fleft(1,frac{1}{2}right) \ f(-1,1) & fleft(-frac{1}{2},1right) & f(0,1) & fleft(frac{1}{2},1right) & f(1,1) \ end{array} right)$

Или, если исключить граничные значения, которые всё равно равны нулю, то координаты будут считаться по формуле

$frac{2 index-size+1}{size}$

а матрица соответственно примет вид

$left( begin{array}{ccccc} fleft(-frac{4}{5},-frac{4}{5}right) & fleft(-frac{2}{5},-frac{4}{5}right) & fleft(0,-frac{4}{5}right) & fleft(frac{2}{5},-frac{4}{5}right) & fleft(frac{4}{5},-frac{4}{5}right) \ fleft(-frac{4}{5},-frac{2}{5}right) & fleft(-frac{2}{5},-frac{2}{5}right) & fleft(0,-frac{2}{5}right) & fleft(frac{2}{5},-frac{2}{5}right) & fleft(frac{4}{5},-frac{2}{5}right) \ fleft(-frac{4}{5},0right) & fleft(-frac{2}{5},0right) & f(0,0) & fleft(frac{2}{5},0right) & fleft(frac{4}{5},0right) \ fleft(-frac{4}{5},frac{2}{5}right) & fleft(-frac{2}{5},frac{2}{5}right) & fleft(0,frac{2}{5}right) & fleft(frac{2}{5},frac{2}{5}right) & fleft(frac{4}{5},frac{2}{5}right) \ fleft(-frac{4}{5},frac{4}{5}right) & fleft(-frac{2}{5},frac{4}{5}right) & fleft(0,frac{4}{5}right) & fleft(frac{2}{5},frac{4}{5}right) & fleft(frac{4}{5},frac{4}{5}right) \ end{array} right)$

После того, как элементы матрицы были рассчитаны по формуле, необходимо посчитать их сумму и поделить матрицу на неё. К примеру, если у нас получилась матрица

$left( begin{array}{ccc} 1 & 4 & 1 \ 4 & 20 & 4 \ 1 & 4 & 1 \ end{array} right)$

то суммой всех её элементов будет 40, и после нормализации она примет вид

$left( begin{array}{ccc} frac{1}{40} & frac{1}{10} & frac{1}{40} \ frac{1}{10} & frac{1}{2} & frac{1}{10} \ frac{1}{40} & frac{1}{10} & frac{1}{40} \ end{array} right)$

и суммой всех её элементов станет 1.

Линейное затухание

Для начала возьмём самую простую функцию — линию:

$left{ begin{array}{ll} 1-x, & x<1 \ 0, & x geqslant 1 \ end{array} right.$

Нужно больше разных Blur-ов - 34

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

Нужно больше разных Blur-ов - 35

Мягкое линейное затухание

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

$1-frac{n x-x^n}{n-1}$

в которой $n$ определяет «жёсткость» стыковки, $n>1$. Для, например, $n=3$ получим

$left{ begin{array}{ll} 1-frac{3 x-x^3}{2}, & x<1 \ 0, & x geqslant 1 \ end{array} right.$

Нужно больше разных Blur-ов - 41

а сам фильтр будет выглядеть как

Нужно больше разных Blur-ов - 42

Гиперболическое затухание

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

Нужно больше разных Blur-ов - 43

После всех вычислений и упрощений получим формулу

$left{ begin{array}{ll} frac{(x-1)^2 (k x+k+1)}{(k+1) (k x+1)}, & x<1 \ 0, & x geqslant 1 \ end{array} right.$

в которой параметр $k>0$ определяет характер затухания:

Нужно больше разных Blur-ов - 46

а сам фильтр будет выглядеть (для $k=5$) как

Нужно больше разных Blur-ов - 48

Имитация эффекта боке

Можно пойти и другим путём — делать вершину фильтра не острой, а тупой. Наиболее простой способ реализовать это — задать функцию затухания как константу:

$left{ begin{array}{ll} 1, & x<1 \ 0, & x geqslant 1 \ end{array} right.$

Нужно больше разных Blur-ов - 50

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

$left{ begin{array}{ll} left(1-x^nright)^2, & x<1 \ 0, & x geqslant 1 \ end{array} right.$

Варьируя параметр $n$, можно получить широкий спектр вариантов фильтра:

$n=0.5$

Нужно больше разных Blur-ов - 54

$n=2$

Нужно больше разных Blur-ов - 56

$n=10$

Нужно больше разных Blur-ов - 58

$n=50$

Нужно больше разных Blur-ов - 60

А слегка модифицировав функцию затухания, можно сделать более выраженным кольцо на краях фильтра, например так:

$left{ begin{array}{ll} left(1-x^nright)^2 left(d+x^mright), & x<1 \ 0, & x geqslant 1 \ end{array} right.$

Здесь параметр $d$ определяет высоту центра, а $m$ — резкость перехода к краям.
Для $d=0.2, m=2, n=10$ получим

Нужно больше разных Blur-ов - 65

а для $d=0, m=12, n=2$

Нужно больше разных Blur-ов - 67

Вариации гауссианы

Можно модифицировать и непосредственно саму функцию гауссианы. Наиболее очевидный способ для этого — параметрировать показатель степени — мы сейчас рассматривать не будем, а возьмём более интересный вариант:

$left{ begin{array}{ll} e^{frac{k x^2}{x^2-1}}, & -1<x<1 \ 0, & otherwise \ end{array} right.$

За счёт того, что при $x$ стремящемся к единице знаменатель $x^2-1$ стремится к нулю, дробь $frac{k x^2}{(x^2-1)}$ стремится к минус бесконечности, а сама экспонента также стремится к нулю. Таким образом, деление на $x^2-1$ позволяет сжать область определения функции с $(-infty, infty)$ до $(-1,1)$. При этом, при $x=pm 1$ за счёт деления на ноль ($0^2-1=0$) значение функции не определено, но имеет два предела — предел с одной стороны (изнутри) равен нулю, а с другой стороны — бесконечности:

$underset{xto 1^-}{text{lim}}e^{frac{k x^2}{x^2-1}}=0$

$underset{xto 1^+}{text{lim}}e^{frac{k x^2}{x^2-1}}=infty$

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

Параметр $k$ определяет схожесть с гауссианой — чем он больше, тем сильнее получается схожесть — за счёт того, что всё более линейный участок $frac{1}{x^2-1}$ приходиться на центр функции. Можно было бы предположить, что за счёт этого в пределе можно получить оригинальную гауссиану — но, к сожалению, нет — функции всё-таки разные.

Нужно больше разных Blur-ов - 81

Теперь можно посмотреть, что получилось:

$k=5$

Нужно больше разных Blur-ов - 83

$k=2$

Нужно больше разных Blur-ов - 85

$k=0.5$

Нужно больше разных Blur-ов - 87

$k=0.1$

Нужно больше разных Blur-ов - 89

$k=0.01$

Нужно больше разных Blur-ов - 91

Вариации формы

Изменив функцию перехода от двух координат к одной $sqrt{x^2+y^2}$, можно получить и другие фигуры, а не только диск. Например:

$fleft(frac{left| x-yright| +left| x+yright|}{2}right)$

Нужно больше разных Blur-ов - 94

$f(left| xright| +left| yright| )$

Нужно больше разных Blur-ов - 96

Перейдя на комплексные числа, можно конструировать и более сложные фигуры:

$ fleft( frac{ left| Releft((x+i y) (-1)^{frac{0}{3}}right)right| + left| Releft((x+i y) (-1)^{frac{1}{3}}right)right| + left| Releft((x+i y) (-1)^{frac{2}{3}}right)right| }{sqrt{3}} right) $

Нужно больше разных Blur-ов - 98

$fbiggl(10left| Releft((x+i y) (-1)^{frac{1}{8}}right)right|biggr) cdot f(left| x+i yright|)$

Нужно больше разных Blur-ов - 100

$fbiggl(biggl| 5 left| x+i yright| (x+i y) Rebiggl(cos left(frac{5}{2} arg (x+i y)right)biggr)biggr| biggr) cdot f(left| x+i yright| ) $

Нужно больше разных Blur-ов - 102

При этом нужно следить, чтобы при преобразовании координат не выходить за пределы интервала $(0,1)$ — ну или наоборот, доопределить функцию затухания для отрицательных значений аргумента.

Несколько конкретных примеров

Статья была бы не полной без практического испытания на конкретных изображениях. Поскольку у нас не научная работа, то и изображение Лены мы брать не будем — а возьмём что-нибудь мягкое и пушистое:

Нужно больше разных Blur-ов - 104

Гауссиана

Нужно больше разных Blur-ов - 105

Нужно больше разных Blur-ов - 106

Гиперболическое затухание

Нужно больше разных Blur-ов - 107

Нужно больше разных Blur-ов - 108

Крест

Нужно больше разных Blur-ов - 109

Нужно больше разных Blur-ов - 110

Кольцо

Нужно больше разных Blur-ов - 111

Нужно больше разных Blur-ов - 112

Одностороннее затухание

Нужно больше разных Blur-ов - 113

Нужно больше разных Blur-ов - 114

Те же фильтры, но для текста:

Нужно больше разных Blur-ов - 115
Нужно больше разных Blur-ов - 116
Нужно больше разных Blur-ов - 117
Нужно больше разных Blur-ов - 118
Нужно больше разных Blur-ов - 119
Нужно больше разных Blur-ов - 120

Заключение

Аналогичным образом можно строить и более сложные фильтры, в том числе и с усилением резкости или выделением контуров; а также модифицировать уже рассмотренные.

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

Более подробно вывод функций для стыковки с константой рассматривается здесь. В качестве функции затухания также могут быть использованы оконные функции, рассмотренные здесь — нужно лишь масштабировать аргумент c (0,1) на ($frac{1}{2}$,1) или изначально считать оконные функции по формуле $frac{1}{2} left(fleft(frac{t x+1}{t-1}right)-fleft(frac{t x-1}{t-1}right)right)$.

Исходный документ Wolfram Mathematica для этой статьи можно скачать здесь.

Автор: Refridgerator

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js