Pull to refresh

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

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


Введение


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

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



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



Здесь для каждой пары координат $(x,y)$ рассчитывается расстояние до центра по формуле $\sqrt{x^2+y^2}$, которое передаётся как аргумент в функцию гауссианы — и, как легко увидеть, $e^{-\left(\sqrt{x^2+y^2}\right)^2}$ сокращается до $e^{-(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) $


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



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

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

Для удобства часто используют нормализацию и по координатам, посредством введения дополнительного параметра $\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$


За счёт того, что выполняется равенство $e^{-\left(x^2+y^2\right)}=e^{-x^2} e^{-y^2}$, размытие по Гауссу можно реализовать последовательно сначала по строкам, а затем по столбцам — что позволяет достаточно сильно сэкономить на вычислениях. В этом случае необходимо использовать формулу с нормализацией для одномерного случая —

$\frac{e^{-\frac{x^2}{2 \sigma ^2}}}{\sqrt{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) & f\left(-\frac{1}{2},-1\right) & f(0,-1) & f\left(\frac{1}{2},-1\right) & f(1,-1) \\ f\left(-1,-\frac{1}{2}\right) & f\left(-\frac{1}{2},-\frac{1}{2}\right) & f\left(0,-\frac{1}{2}\right) & f\left(\frac{1}{2},-\frac{1}{2}\right) & f\left(1,-\frac{1}{2}\right) \\ f(-1,0) & f\left(-\frac{1}{2},0\right) & f(0,0) & f\left(\frac{1}{2},0\right) & f(1,0) \\ f\left(-1,\frac{1}{2}\right) & f\left(-\frac{1}{2},\frac{1}{2}\right) & f\left(0,\frac{1}{2}\right) & f\left(\frac{1}{2},\frac{1}{2}\right) & f\left(1,\frac{1}{2}\right) \\ f(-1,1) & f\left(-\frac{1}{2},1\right) & f(0,1) & f\left(\frac{1}{2},1\right) & f(1,1) \\ \end{array} \right)$


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

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


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

$\left( \begin{array}{ccccc} f\left(-\frac{4}{5},-\frac{4}{5}\right) & f\left(-\frac{2}{5},-\frac{4}{5}\right) & f\left(0,-\frac{4}{5}\right) & f\left(\frac{2}{5},-\frac{4}{5}\right) & f\left(\frac{4}{5},-\frac{4}{5}\right) \\ f\left(-\frac{4}{5},-\frac{2}{5}\right) & f\left(-\frac{2}{5},-\frac{2}{5}\right) & f\left(0,-\frac{2}{5}\right) & f\left(\frac{2}{5},-\frac{2}{5}\right) & f\left(\frac{4}{5},-\frac{2}{5}\right) \\ f\left(-\frac{4}{5},0\right) & f\left(-\frac{2}{5},0\right) & f(0,0) & f\left(\frac{2}{5},0\right) & f\left(\frac{4}{5},0\right) \\ f\left(-\frac{4}{5},\frac{2}{5}\right) & f\left(-\frac{2}{5},\frac{2}{5}\right) & f\left(0,\frac{2}{5}\right) & f\left(\frac{2}{5},\frac{2}{5}\right) & f\left(\frac{4}{5},\frac{2}{5}\right) \\ f\left(-\frac{4}{5},\frac{4}{5}\right) & f\left(-\frac{2}{5},\frac{4}{5}\right) & f\left(0,\frac{4}{5}\right) & f\left(\frac{2}{5},\frac{4}{5}\right) & f\left(\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.$




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



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


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

$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.$




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



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


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



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

$\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$ определяет характер затухания:



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



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


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

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




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

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


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

$n=0.5$


$n=2$


$n=10$


$n=50$



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

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


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



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



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


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

$\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$ за счёт деления на ноль ($1^2-1=0$) значение функции не определено, но имеет два предела — предел с одной стороны (изнутри) равен нулю, а с другой стороны — бесконечности:

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


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


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

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



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

$k=5$


$k=2$


$k=0.5$


$k=0.1$


$k=0.01$



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


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

$f\left(\frac{\left| x-y\right| +\left| x+y\right|}{2}\right)$




$f(\left| x\right| +\left| y\right| )$




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

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





$f\biggl(10\left| \Re\left((x+i y) (-1)^{\frac{1}{8}}\right)\right|\biggr) \cdot f(\left| x+i y\right|)$




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





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

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


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



Гауссиана




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




Крест




Кольцо




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




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








Заключение


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

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

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

Исходный документ Wolfram Mathematica для этой статьи можно скачать здесь.
Tags:
Hubs:
Total votes 54: ↑53 and ↓1+52
Comments11

Articles