Изменения

Перейти к: навигация, поиск

Блендинг изображений

5288 байт добавлено, 15:21, 23 января 2021
м
Эксперимент с вертикальными картинками
Копирование элемента одного изображения и его вставка на другое изображение {{---}} один из наиболее используемых методов для создания графического контента. Простая вставка, как правило, бросается в глаза и делает результат похожим на коллаж, во многих случаях этот эффект является нежелательным.
{{Определение
|definition =
'''Блендинг изображений''' (англ. ''image blending'') {{---}} метод, позволяющий вставить часть одного изображения в другое таким образом, чтобы композиция изображений выглядела естественно, без швов на границах вставки . }}Основная трудность задачи заключается в том, что естественность результата зависит не только от бесшовности наложения, но и соответсвующими цветами от схожести цветов и текстурамитекстуры вставляемого и фонового изображений. }  {|! Вставляемое изображение! Фоновое изображение! Простая вставка! Желаемый результат|-| [[Файл:Diver bl diver.png|180px]]| [[Файл:Diver bl sea.png|180px]]| [[Файл:Diver bl2.png|180px]]| [[Файл:Diver bl3.png|180px]]|}
==Блендинг Пуассона==
[[Файл:Poisson int1.png|thumb|right|300px250px|Рис. Рисунок $1.1$. : Пример перепада яркости при простой вставке<ref name='ZWS20'/>]][[Файл:Poisson int2.png|thumb|right|300px250px|Рис. Рисунок $1.2$. : Результат применения блендинга Пуассона<ref name='ZWS20'/>]]
Простая вставка одного изображения поверх другого нередко влечет заметный перепад яркости на границе вставки (рис. рисунок $1.1$). Метод Пуассона заключается в сглаживании этого перепада (рис. рисунок $1.2$) с целью сделать дефект менее заметным, используя градиент вставляемого изображения и значения пикселей фонового изображения на границе вставки.
'''Замечание:''' Для RGB изображений задача минимизации решается для каждого цветового канала отдельно.
! Маска $M$
|-
| [[Файл:Poisson_cat.jpg|200px155px]]| [[Файл:Poisson_cherry.jpg|200px155px]]| [[Файл:Poisson_cherry_mask.png|200px155px]]
|}
Пусть $f_S$ {{---}} скалярная функция, определенная на $P \setminus int(\Omega)$, задает фоновое изображение $S$; $f$ {{---}} неизвестная скалярная функция, определенная на $int(\Omega)$, задает, каким образом должно выглядеть результат блендинга в области вставки.
$v_I$ {{---}} векторное поле, определенное на $\Omega$. В качестве $v_I$ возьмем градиент вставляемого изображения $I$: $v_I = \nabla f_I$.
Нашей задачей является поиск такой функции $f$, чтобы блендинговое изображение выглядело реалистично. Для этого минимизируем разность градиента функции $f$ и векторного поля $v_I$, считая, что $f = f_S$ на границе $\Omega$.
$$
\underset{f}{\mathrm{min}} \underset{\Omega}{\iint} |\nabla f - v_I|^2, \text{где } f|_{\partial \Omega} = f_S|_{\partial \Omega}.
$$
Решение задачи минимизации является единственным решением уравнения Пуассона для граничных условий Дирихле.
=== Дискретный случай ===
Пусть $p$ {{---}} координаты $(x, y)$ пикселя двухмерного изображения. За $Img_p$ обозначим значение пикселя с координатами $p$ изображения $Img$. Пусть $\Omega = \left\{ p\;|\;M_p = 1 \right\}$ {{---}} область, заданная маской $M$. Тогда $\partial \Omega$ {{---}} координаты границы вставляемой области, а $int(\Omega)$ {{---}} внутренность области.
Пусть $N_p$ {{---}} множество соседей $p$ (максимум четыре пикселя, имеющих общую границу с $p$, т.е. пиксели со следующими координатами: $(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)$). Для всех пар $(p, q)$ таких, что $q \in N_p$, введем $v_{pq} = I_p - I_q$.
Введем переменные $O_p, p \in \Omega$. Так как мы хотим сделать результат бесшовным, пиксели $O_p, p \in \partial\Omega$, сделаем равными $S_p$. Для $p, q \in int(\Omega),\; q \in N_p$ постараемся найти такое $O$, чтобы разность $O_p$ и $O_q$ была близка к $v_{pq}$. Для этого решим задачу минимизации:
$$
\underset{O_p,\; p \in \Omega}{\mathrm{min}}\; \underset{p, q \in \Omega}{\sum}\; \left(O_p - O_q - v_{pq}\right)^2, \text{где } O_p = S_p, p \in \partial \Omega.
$$
Заметим, что функция, которую мы хотим минимизировать, квадратична относительно переменных $O_p, p \in int(\Omega)$. Для решения задачи минимизации вычислим частные производные по этим переменным и найдем значения переменных, при которых частные производные будут равны нулю.
$$\frac{\partial{\underset{p, q \in \Omega}{\sum}\; \left(O_p - O_q - v_{pq}\right)^2}}{\partial O_p} = \underset{q \in N_p}{\sum} 2 \left(O_p - O_q - v_{pq}\right) - \underset{q \in N_p}{\sum} 2 \left(O_q - O_p - v_{qp}\right) = 2 \underset{q \in N_p}{\sum} 2 \left(O_p - O_q - v_{pq}\right).$$.
Приравнивая к нулю, получаем: $|N_p| O_p - \underset{q \in N_p}{\sum} O_q = \underset{q \in N_p}{\sum} v_{pq}$.
O_p,\; \text{если } p \in int(\Omega) \\
S_p,\; \text{иначе }
\end{cases}.
$$
Mетод Пуассона сдвигает цвета накладываемого изображения, сохраняя свойства градиента (т.е. если пиксель $I_{p1}$ был меньше $I_{p2}$, то после преобразования $I_{p1}$ не станет больше $I_{p2}$), однако само значение градиета может получиться другим.<ref name='clear_poisson'>https://erkaman.github.io/posts/poisson_blending.html Poisson blending для самых маленьких</ref>
==Трансфер Нейронный перенос стиля==
{{main|Neural Style Transfer}}
Прежде чем переходить к гармонизации картин, рассмотрим задачу трансфера нейронного переноса стиля с изображения $S$ на изображение $I$. Для этого используются выходы скрытых слоёв [[Сверточные нейронные сети | свёрточной нейронной сети]] VGG-19<ref name="SZ14">[https://arxiv.org/pdf/1409.1556.pdf Very Deep Convolutional Networks for Large-Scale Image Recognition] Karen Simonyan, Andrew Zisserman (2014)</ref>(конкретные слои указаны ниже в деталях реализации).
Основная идея генерации изображения {{---}} решение оптимизационной задачи $\mathcal{L}(O, I, S, O) \xrightarrow[O]{} min$, где $O$ {{---}} итоговое изображение, $\mathcal{L}(O, I, S, O)$ {{---}} [[Функция потерь и эмпирический риск | функция потерь]]. Такую задачу можно решать градиентным спуском в пространстве изображений используя [[обратное распространение ошибки | метод обратного распространения ошибки]].
{{Определение
|definition =
Пусть $F^l\left[I\right] \in \mathcal{R}^{N_l \times M_l}$ {{---}} выход матрица значений выхода $l$-го слоя сети на изображении $I$. Выход $l$-го слоя сети имеет размерность $N_l \times W_l \times H_l$. Представим его как матрицу $N_l \times M_l$, где $N_l$ {{---}} количество фильтров в $l$-ом слое, $M_l$ {{---}} количество признаков (высота, умноженная на ширину$M_l = W_l H_l$). Тогда $F^l_{ij}\left[I\right]$ {{---}} $j$-ый признак $i$-го фильтра в $l$-ом слое. Столбец матрицы $F^l\left[I\right]$ размера $N_l$ назовём '''вектором активации'''.}}
{{Определение
|definition =
'''Матрица Грама''' (англ. ''Gram matrix'') {{---}} матрица попарных скалярных произведений. В нашем случае матрица отражает корреляцию между выходами фильтров. $$G^l\left[IS\right] \in \mathcal{R}^{N_l \times N_l} ,$$$$G^l\left[S\right] = F^l\left[IS\right]F^l\left[IS\right]^T.$$.}} Далее рассмотренны функции потерь, которые мы будем использовать. ===Content loss===
===Алгоритм Гатиса<ref name="GEB16">$F^l\left[https://rn-unisonI\right]$ отражает содержание изображения.githubМы хотим чтобы содержание результата было как можно ближе к исходной картинке.io/articulos/style_transfer.pdf Image Style Transfer Using Convolutional Neural Networks] Leon A. GatysВведём для этого такую функцию потерь:$$\mathcal{L}_{content}(I, Alexander S. EckerO) = \displaystyle\sum_l \frac{\alpha_l}{2 N_l M_l}\displaystyle\sum_{i, Matthias Bethge j} \left(2016F^l_{ij}\left[I\right] - F^l_{ij}\left[O\right]\right)</ref>===^2,$$где $\alpha_l$ {{---}} вклад $l$-го слоя в функцию потерь.
{{Определение|id=content_loss_def|definition =$\mathcal{L}^{\alpha}_{content}(I, O) = \displaystyle\sum_l \frac{\alpha_l}{2 N_l M_l}\displaystyle\sum_{i, j} \left(F^l_{ij}\left[I\right] - F^l_{ij}\left[O\right]\right)^2$ {{---}} функция потерь содержания, где $\alpha_l$ {{---}} вклад $l$-го слоя в функцию потерь<ref nameStyle loss="NotOriginalDef">Здесь используется определение функции потерь, которое отличается от статьи Гатиса, но используется в таком виде в статье про гармонизацию.</ref>.}}{{Определение|id=style_loss_def|definition =$\mathcal{L}^{\beta}_{style}(I, O) = \displaystyle\sum_l \frac{\beta_l}{2N_l^2} \displaystyle\sum_{i, j} \left(G^l_{ij}\left[I\right] - G^l_{ij}\left[O\right]\right)^2$ {{---}} функция потерь стиля, где $\beta_l$ {{---}} вклад $l$-го слоя в функцию потерь<ref name="NotOriginalDef"/>.}}
Итоговой функцией $G^l\left[S\right]$ отражает статистику выходов фильтров независимо от их расположения, что, в свою очередь, отражает стиль изображения. Чтобы стиль результата был похож на стилевое изображение, введём следующую функцию потерь будет :$$\mathcal{L}_{Gatysstyle} (S, O) = \mathcaldisplaystyle\sum_l \frac{L\beta_l}{2N_l^{2} \displaystyle\alpha}_sum_{contenti, j}\left(I, O) + w_G^l_{styleij}\mathcalleft[S\right] - G^l_{Lij}^{\beta}_{style}(I, left[O\right]\right)^2,$<ref name="NotOriginalDef"/>. Вес $w_{style}$, векторы где $\alphabeta_l$ и {{---}} вклад $\betal$ являются, -го слоя в некотором смысле, гиперпараметрами алгоритма, которые нужно подбиратьфункцию потерь.
Авторы статьи показывают, что в качестве начальной инициализации можно брать изображение $I$, изображение $S$ или белый шум {{---}} алгоритм даёт похожие результаты в этих случаях.===Gatys' loss===
Скомбинируем $\mathcal{L}_{content}$ и $\mathcal{L}_{style}$ и получим функцию потерь, которая была использована в алгоритме Гатиса<ref name="GEB16">[[Файлhttps:GEB16_Figure_6//rn-unison.png|1000px|thumb|center|Начальная инициализация: '''github.io/articulos/style_transfer.pdf Image Style Transfer Using Convolutional Neural Networks] Leon A. Gatys, Alexander S. Ecker, Matthias Bethge (2016)''' </ref>:$O_0 $\mathcal{L}_{Gatys}(I, S, O) = \mathcal{L}_{content}(I$; '''B, O) + w_{style}\mathcal{L}_{style}(S, O)''' .$O_0 = S$; '''C)''' Вес $O_0 = randomw_{style}$, векторы $4\alpha$ примера инициализированы различными белыми шумами ]]и $\beta$ являются, в некотором смысле, гиперпараметрами алгоритма, которые мы выберем позднее.
===Histogram Loss===
Авторы другой статьи<ref name="WRB17">[https://arxiv.org/pdf/1701.08893.pdf Stable and Controllable Neural Texture Synthesis and Style Transfer Using Histogram Losses] Eric Risser, Pierre Wilmot, Connelly Barnes (2017)</ref> показывают, что результаты, полученные с помощью $\mathcal{L}_{Gatys}$ нестабильны и предложили другую учитывать ещё одну функцию потерь, основанную на '''сопоставлении гистограмм'''.
{{Определение
|definition =
'''Сопоставление гистограмм''' (англ. ''Histogram matching'') {{---}} метод обработки изображения, после которого гистограмма изображения совпадает с целевой гистограммой<ref name="HistMatch">https://en.wikipedia.org/wiki/Histogram_matching</ref>.}}
{{Определение|definition =Пусть $R = histmatch(S, O)$ {{---}} отображение пикселей такое, что гистограмма $S$ совпадает с гистограммой $R(O)$.}}{{Определение|id=hist_loss_def|definition =, тогда Histogram loss будет выглядеть так:$$\mathcal{L}^{\gamma}_{hist}(S, O) = \displaystyle\sum_l \gamma_l \displaystyle\sum_{i, j} \left(F^l_{ij}\left[O\right] - R\left(F^l_{ij}\left[O\right]\right)\right)^2,$ {{---}} функция потерь гистограмм, $где$\gamma_l$ {{---}} вклад $l$-го слоя в функцию потерь}}.
'''Замечание:''' Если в случае остальных функций потерь нетрудно посчитать производную, то здесь могут возникнуть проблемы. Но поскольку $\displaystyle\frac{\partial \mathcal{L}_{hist}}{\partial F^l_{ij}\left[O\right]}$ является нулём почти везде, авторы предлагают при подсчёте производной считать $R\left(F^l_{ij}\left[O\right]\right)$ константой, которая не зависит от $O$.
===Total variation loss===
Также добавим ещё одну функцию потерь, которая удаляет шумы, при этом сохраняя важные детали изображения<ref name="MV15">[https://arxiv.org/pdf/1412.0035.pdf Understanding Deep Image Representations by Inverting Them] Aravindh Mahendran, Andrea Vedaldi (2015)</ref><ref name="JAFF16">[https://arxiv.org/pdf/1603.08155.pdf Perceptual Losses for Real-Time Style Transfer and Super-Resolution] Justin Johnson, Alexandre Alahi, Li Fei-Fei (2016)</ref>.{{Определение:|id=tv_loss_def|definition =$$\mathcal{L}_{tv}(O) = \displaystyle\sum_{i, j} \left(O^l_{i, j} - O^l_{i-1, j}\right)^2 + \left(O^l_{i, j} - O^l_{i, j-1}\right)^2.$$ {{---}} общая вариационная потеря (англ. ''Total variation loss'').}}
==Глубокая гармонизация картин<ref name="LPSB18">https://arxiv.org/pdf/1804.03189.pdf Fujun Luan, Sylvain Paris, Eli Shechtman, Kavita Bala (2018)</ref>==
Для того чтобы вставить изображение в картину или рисунок нужно не только сделать бесшовный переход и изменить цвета, но ещё и изменить текстуру вставляемого изображения, например , сымитировать мазки кистью(рисунок $2$). Используем для этого комбинацию подходов из других статей<ref name="GEB16"/><ref name="JAFF16"/><ref name="WRB17"/>.
<div class="oo-ui-panelLayout-scrollable" style="display: block; vertical-align:middle; height: auto; max-width: auto; float: center">[[Файл:LPSB18_Figure_1.png|1000px750px|thumb|center|Рисунок $2$: Пример работы алгоритма ''Deep Image Analogy''<ref name="LYY*17">[https://arxiv.org/pdf/1705.01088.pdf Visual Attribute Transfer through Deep Image Analogy] Jing Liao, Yuan Yao, Lu Yuan, Gang Hua, Sing Bing Kang (2017)</ref> ($3 $ картинка) и ''Deep Painterly Harmonization''<ref name="LPSB18"/> ($4 $ картинка)]]</div>Алгоритм будет состоять состоит из двух проходов. Первый проход будет делать делает грубую гармонизацию, а второй {{---}} более тщательную. Отличаться Отличаются они будут '''стилевым маппингом''' и функциями потерь<ref name="LPSB18">https://arxiv.org/pdf/1804.03189.pdf Fujun Luan, Sylvain Paris, Eli Shechtman, Kavita Bala (2018)</ref>.
{{Определение
|definition =
'''Стилевым маппингом''' мы будем называть назовём отображение $P : \mathcal{R}^{N_l \times M_l} \rightarrow \mathcal{R}^{N_l \times M_l}$, которое некоторым образом переставляет столбцы матрицы (не обязательно обратимо, то есть столбцы могут теряться и копироваться). Более формально, пусть $p(j)$ {{---}} новая позиция столбца $j$, тогда $P(Q)_{i, p(j)} = Q_{ij}$.}}
Один проход будет состоять состоит из $3$ частей:
# Входное $I$ и стилевое $S$ изображения подаются на вход нейронной сети VGG-19, так мы получаем $F^l_{ij}\left[I\right]$ и $F^l_{ij}\left[S\right]$.
# Для каждого слоя $l$ некоторым алгоритмом $\pi$ cтроится стилевой маппинг $P_l$, который сопоставляет столбцам из $F_l[I]$ столбцы из $F_l[S]$.
# Изображение $O$ восстанавливается градиентным спуском по пространству изображений, используя некоторую функцию с использованием функции потерь $\mathcal{L}$.
<font size="3em">
'''fun''' $SinglePassHarmonization$(
<span style="display: inline-block; width: 2em3em">$I$,</span><font color="green">// Входное изображение </font> <span style="display: inline-block; width: 2em3em">$M$,</span><font color="green">// Маска </font> <span style="display: inline-block; width: 2em3em">$S$,</span><font color="green">// Стилевое изображение </font> <span style="display: inline-block; width: 2em3em">$\pi$,</span><font color="green">// Алгоритм построения стилевого маппинга </font> <span style="display: inline-block; width: 2em3em">$\mathcal{L}$</span><font color="green">// Функция потерь </font>
):
<font color="green">// Строим матрицы $F[I]$ и $F[S]$ с помощью свёрточной сети VGG-19 </font>
<font color="green">// Градиентным спуском ищем изображение $O$, которое минимизирует $\mathcal{L}$ </font>
$O \leftarrow Reconstruct(I, M, S, P, \mathcal{L})$
'''return''' $O$
</font>
{{Определение
|definition =
'''Вектор активации''' (англ. ''activation vector'') {{---}} это вектор значений функции активации для каждого фильтра свёрточного слоя. Заметим, что столбцы $F_l$ являются векторами активации.}} {{Определение|definition ='''Патчем''' (англ. ''patch'') для столбца $j$ будем называть тензор $3 \times 3 \times N_l$, который состоит из соседних векторов активации в тензоре выхода свёрточного слоя, с центром в столбце $(x, y)$, где $j= y W_l + x$.}}
<!--
{| class="wikitable" style="float:right; clear:right;"
|-
| [[Файл:LPSB18_Figure_2b.png|250px|thumb|none|Результаты после первого прохода]]
| [[Файл:LPSB18_Figure_2c.png|250px|thumb|none|Результаты после второго прохода]]
|}
-->
<div class="tright" style="clear:none">[[Файл:LPSB18_Figure_2c.png|250px|thumb|none|Рисунок $3.2$: Результаты после второго прохода<ref name="WRB17"/>]]</div><div class="tright" style="clear:none">[[Файл:LPSB18_Figure_2b.png|250px|thumb|none|Рисунок $3.1$: Результаты после первого прохода<ref name="WRB17"/>]]</div>
Первый проход делает грубую гармонизацию, но при этом он хорошо работает с любыми стилями(рисунок $3.1$). Здесь используется алгоритм <code>$IndependentMapping</code> $ для построения стилевого маппинга. Этот алгоритм для каждого столбца $j$ в $F_l[I]$ ищет столбец $p(j)$ в $F_l[S]$, такой что евклидово расстояние между патчем $F_l[I]$ с центром $j$ и патчем $F_l[S]$ с центром $p(j)$ минимально (метод ближайшего соседа).
<font size="3em">
'''fun''' $IndependentMapping$(
<span style="display: inline-block; width: 4em5em">$F[I]$,</span><font color="green">// Выходы слоёв после входного изображения </font> <span style="display: inline-block; width: 4em5em">$Mask$,</span><font color="green">// Маска </font> <span style="display: inline-block; width: 4em5em">$F[S]$</span><font color="green">// Выходы слоёв после стилевого изображения </font>
):
<font color="green">// Для всех слоёв от $1$ до $L$ </font>
</font>
В первом проходе используется модифицированная функция потерь $\mathcal{L}_{Gatys}$, с тем лишь отличием, что в $\mathcal{L}_{style}$ к $F_l[S]$ применяется стилевой маппинг $P_l$.:
$$\mathcal{L}_1(I, S, O, P) = \mathcal{L}^{\alpha}_{content}(I, O) + w_{style}\mathcal{L}^{\beta}_{style}(S, O, P) \text{, где } w_{style} \text{ {{---}} вес стилевой функции потерь}.$$
'''Замечание:''' при посчёте градиента $\mathcal{L}^{\alpha}_{content}$ используются только пиксели внутри маски<ref>https://github.com/luanfujun/deep-painterly-harmonization/blob/a33a9a70366b6baff1cc0291f857b5895b271fc1/neural_gram.lua#L349</ref>.
===Второй проход===
[[Файл:LPSB18_Figure_5c.png|thumb|right|250px|Рисунок $4.1$: Только первый проход<!--ref name="WRB17"/>]][[Файл:LPSB18_Figure_2cLPSB18_Figure_5d.png|thumb|right|250px|Рисунок $4.2$: Только второй проход<ref name="WRB17"/>]][[Файл:LPSB18_Figure_5f.png|thumb|right|250px|Рисунок $4.3$: Результат с $\mathcal{L}_{style}$ вместо $\mathcal{L}_{s1}$<ref name="WRB17"/>]][[Файл:LPSB18_Figure_5g.png|thumb|right|Результаты после второго 250px|Рисунок $4.4$: Оба прохода<ref name="WRB17"/>]]--[[Файл:LPSB18_Figure_5h.png|thumb|right|250px|Рисунок $4.5$: Финальный результат<ref name="WRB17"/>]]
Второй проход делает более качественную гармонизацию после первого прохода(рисунок $3.2$). Здесь мы будем использовать более сложный алгоритм $ConsistentMapping$ построения стилевого маппинга и более сложную функцию потерь. Суть этого алгоритма в том, чтобы найти стилевой мапинг на некотором слое $l_{ref}$ и перенести этот маппинг на остальные слои. Также, мы будем предпочитать маппинги, в которых смежные патчи в $F_l[S]$ остаются смежными после мапинга, чтобы обеспечить пространсвенную согласованность (видимо таким образом мы хотим переносить сложные текстуры более качественно, например , мазки кистью). Если применять второй проход сразу, то результаты получаются хуже (рисунок $4.2$).
<font size="3em">
'''fun''' $ConsistentMapping$(
<span style="display: inline-block; width: 4em5em">$F[I]$,</span><font color="green">// Выходы слоёв после входного изображения </font> <span style="display: inline-block; width: 4em5em">$Mask$,</span><font color="green">// Маска </font> <span style="display: inline-block; width: 4em5em">$F[S]$</span><font color="green">// Выходы слоёв после стилевого изображения </font>
):
<font color="green">// Сначала посчитаем маппинг как в IndependentMapping только для слоя $l_{ref}$ </font>
$CSet \leftarrow \{q\}$
<font color="green">// Перебираем все смежные патчи </font>
'''for''' $o \in \left\{N, NE, E, SE, S, SW, W, NW\right\}$:
<font color="green">// Добавляем в кандидаты патч, сосед которого является маппингом для нашего соседа в соответсвующем направлении </font>
$CSet \leftarrow CSet \cup \left\{P_0(j + o) - o\right\}$
<font color="green">// Переносим позицию $q$ обратно на слой $l$</font>
$P_l(j) \leftarrow ChangeResolution(l_{ref}, l, q)$
'''return''' $P$
</font>
При вычислении стилевого маппинга появляется очень много дублирующихся векторов, что даёт не очень хорошие результаты(рисунок $4.3$). Поэтому при вычислении матрицы Грама выкинем повторяющиеся векторы. Назовём эту функцию потерь с такой модификацией $\mathcal{L}_{s1}$.
$$\mathcal{L}_2(I, S, O, P) = \mathcal{L}^{\alpha}_{content}(I, O) + w_{style}\mathcal{L}^{\beta}_{s1}(S, O, P) + w_{hist}\mathcal{L}^{\gamma}_{hist}(S, O) + w_{tv}\mathcal{L}_{tv}(O) \text{, $$ где } $w_{style}, w_{hist}, w_{tv} \text{ $ {{---}} веса соответсвующих функций потерь}$$.
<!--{| class="wikitable" style="background-color:#FFF; text-align:center"|-| Рисунок $4.1$: Только первый проход<ref name="WRB17"/>| Рисунок $4.2$: Только второй проход<ref name="WRB17"/>| Рисунок $4.3$: Результат с $\mathcal{L}_{style}$ вместо $\mathcal{L}_{s1}$<ref name="WRB17"/>|Рисунок $4.4$: Оба прохода<ref name="WRB17"/>| Рисунок $4.5$: Финальный результат<ref name="WRB17"/>|-| [[Файл:LPSB18_Figure_5c.png|250px|thumb|none|Только второй проход]]| [[Файл:LPSB18_Figure_5d.png|250px]]|thumb[[Файл:LPSB18_Figure_5f.png|none|Только первый проход250px]]| [[Файл:LPSB18_Figure_5fLPSB18_Figure_5g.png|250px]]|thumb[[Файл:LPSB18_Figure_5h.png|none|Результат с $\mathcal{L}_{style}$ вместо $\mathcal{L}_{s1}$250px]]
|}
-->
===Итоговый алгоритм===
Теперь осталось запустить две стадии :
<font size="3em">
'''fun''' $Harmonization$(
<span style="display: inline-block; width: 4em5em">$I$,</span><font color="green">// Входное изображение </font> <span style="display: inline-block; width: 4em5em">$Mask$,</span><font color="green">// Маска </font> <span style="display: inline-block; width: 4em5em">$S$</span><font color="green">// Стилевое изображение </font>
):
<font color="green">// Грубый проход алгоритма. Каждый слой рассматривается отдельно при построении стилевого маппинга. </font>
===Постобработка===
[[Файл:LPSB18_Figure_6abc.png|400px|thumb|right|Рисунок $5$: Результат постобработки (без постобработки, после первой стадии, после второй стадии)<ref name="WRB17"/>]]
Описанный алгоритм даёт хорошие результаты в целом, но при ближайшем рассмотрении могут быть артефакты(рисунок $5$). Поэтому сделаем двухступенчатую постобработку (подробное описание есть в оригинальной статье<ref name="LPSB18"/>):# Переведём изображение в цветовое пространство [https://en.wikipedia.org/wiki/CIELAB_color_space CIELAB$L*\alpha*\beta$] и применим [https://en.wikipedia.org/wiki/Guided_filter Guided filter] для a и b каналов.# С помощью алгоритма PatchMatch<ref name="BSFG09">https://www.researchgate.net/profile/Eli_Shechtman/publication/220184392_PatchMatch_A_Randomized_Correspondence_Algorithm_for_Structural_Image_Editing/links/02e7e520897b12bf0f000000.pdf Connelly Barnes, Eli Shechtman, Adam Finkelstein, Dan B Goldman (2009)</ref> и того же Guided filter делаем так , чтобы все патчи выходного изображения присутсвовали в стилевом (чтобы не было новых объектов или структур).
===Подбор гиперпараметровДетали реализации===
[[Файл:LPSB18_Figure_4.png|400px|thumb|right|Рисунок $6$: Влияние $l_{ref}$ на результат<ref name="WRB17"/>]]
Возьмём $l_{ref}$ = conv4_1(что будет если использовать другие слои видно на рисунке $6$).
Выберем следующие веса для слоёв:
|}
<!--{| class="wikitable"|+ Веса функций потерь|-! $w_{style}$! $w_{hist}$! $w_{tv}$ |-| $\tau$| $\tau$| $\tau\frac{10}{1 + \exp(10^4 * noise(S) - 25)}$|}-->Введём гиперпараметр $\tau$ и возьмём $w_{style} = w_{hist} = \tau$, $w_{tv} = \tau\frac{10}{1 + \exp(10^4 * noise(S) - 25)}$, где $noise(S) = \underset{i,j}{\mathrm{med}}\left\{\left(O^l_{i, j} - O^l_{i-1, j}\right)^2 + \left(O^l_{i, j} - O^l_{i, j-1}\right)^2\right\}$<ref>[https://github.com/luanfujun/deep-painterly-harmonization/blob/a33a9a70366b6baff1cc0291f857b5895b271fc1/neural_paint.lua#L470 код функции $noise$.</ref>.
Для того чтобы подбирать $\tau$ авторы статьи использовали классификатор стилей изображений. Они взяли VGG-19, обучили её классифицировать $18 $ различных стилей. Эти стили были разделены на $3 $ категории с разными $\tau$. Используя $Softmax $ можно интерполировать необходимый $\tau$ по следующей таблице:
{| class="wikitable"
| $10$
|}
 
На рисунке $4.4$ результат алгоритма без подбора гиперпараметров. Видно, что самолёт ярче, чем остальное изображение. С подбором параметров получается более естественный результат (рисунок $4.5$).
===Примеры===
Примеры взяты с [https://github.com/luanfujun/deep-painterly-harmonization/tree/master/results Github авторов].
{|
! Постобработка
|-
| [[Файл:5_target.jpg|300px180px]]| [[Файл:5_naive.jpg|300px180px]]| [[Файл:5_final_res.png|300px180px]]| [[Файл:5_final_res2.png|300px180px]]
|-
| [[Файл:6_target.jpg|300px180px]]| [[Файл:6_naive.jpg|300px180px]]| [[Файл:6_final_res.png|300px180px]]| [[Файл:6_final_res2.png|300px180px]]
|-
| [[Файл:10_target.jpg|300px180px]]| [[Файл:10_naive.jpg|300px180px]]| [[Файл:10_final_res.png|300px180px]]| [[Файл:10_final_res2.png|300px180px]]
|}
 
===Более новые подходы===
 
* [https://arxiv.org/pdf/2006.00809.pdf Foreground-aware Semantic Representations for Image Harmonization]
* [https://arxiv.org/pdf/2009.09169.pdf BargainNet: Background-Guided Domain Translation for Image Harmonization]
==Глубокий блендинг==
Будем считать, что на вход подаются изображения, прошедшие предварительную обработку:
* Используемая для вставки часть $I$ вырезана с помощью маски .* $M$ и $I$ выровнены относительно $S$.* Размеры матриц, задающих $M, S, I$ , совпадают.
'''Примеры входных данных:'''
{| class="wikitable" style="background-color:#FFF; text-align:center"
|-! '''Стилевое <br/> изображение $S$'''<ref name='ZWS20'/>
| [[Файл:Deep bl s1.png|150px]]
| [[Файл:Deep bl s2.png|150px]]
| [[Файл:Deep bl s3.png|150px]]
|-
! '''Накладываемое <br/> изображение $I$'''<ref name='ZWS20'/>
| [[Файл:Deep bl i1.png|150px]]
| [[Файл:Deep bl i2.png|150px]]
| [[Файл:Deep bl i3.png|150px]]
|}
 
На обоих этапах алгоритм минимизирует взвешенную сумму следующих функций потерь:
* [[Блендинг_изображений#content_loss_def|Функция потерь содержания]] $\mathcal{L}_{cont}$ для сохранения содержания накладываемого изображения $I$
* [[Блендинг_изображений#style_loss_def|Функция потерь стиля]] $\mathcal{L}_{style}$ для переноса стиля изображения $S$ на $I$
* [[Блендинг_изображений#hist_loss_def|Гистограмная функция потерь]] $\mathcal{L}_{hist}$ для стабилизации переноса стиля
* [[Блендинг_изображений#tv_loss_def|Функция потерь полного отклонения]] $\mathcal{L}_{tv}$ для удаления шумов
* [[Блендинг_изображений#grad_loss_def|Градиентная функция потерь]] $\mathcal{L}_{grad}$ для бесшовности наложения
 
Для подсчета $\mathcal{L}_{style}$ и $\mathcal{L}_{content}$ авторами статьи<ref name='ZWS20'>[https://openaccess.thecvf.com/content_WACV_2020/papers/Zhang_Deep_Image_Blending_WACV_2020_paper.pdf Deep Image Blending] Lingzhi Zhang, Tarmily Wen, Jianbo Shi (2020)</ref> использовалась сеть VGG-19<ref name="SZ14"/>, обученная на ImageNet<ref name="ImageNet">https://image-net.org/papers/imagenet_cvpr09.pdf J. Deng, W. Dong, R. Socher, L.-J. Li, K. Li, and L. FeiFei. Imagenet: A large-scale hierarchical image database</ref>.
{{Определение
{{Определение
|definition =
'''Дискретный оператор Лапласа''' (фильтр Лапласа) $\mathbf{D}^2$ {{---}} аналог непрерывного оператора Лапласа $\nabla^2$, который позволяет выделять контуры изображения(рисунки $7.1$ и $7.2$).$$\mathbf{D}^2=\begin{bmatrix}0 & 1 & 0\\1 & -4 & 1\\0 & 1 & 0\end{bmatrix}.$$ }}{| class="wikitable" style="float:right; clear:right;"!Рисунок $7.1$:<br>Исходное изображение<ref>https://en.wikipedia.org/wiki/Lenna#/media/File:Lenna_(test_image).png</ref>!Рисунок $7.2$:<br>Применение фильтра Лапласа|-| [[Файл:Lenna.png|220px]]| [[Файл:Lenna_Laplacian_Neg.png|220px]]|}
** TODO картиночка**Для сохранения контуров изображений $S$ и $I$ в области вставки воспользуемся идеей из [[Блендинг изображений#Блендинг Пуассона|метода Пуассона]] и введём следующую функцию потерь<ref name='ZWS20'/>:$$\mathcal{L}_{grad}(S, I, M, O) = \displaystyle\frac{1}{2HW}\displaystyle\sum_{m=1}^H \displaystyle\sum_{n=1}^W \left[ \mathbf{D}^2 B - \left(\mathbf{D}^2 S + \mathbf{D}^2 I\right) \right]^2_{mn},$$где $H, W$ {{---}} высота и ширина изображений. $B = CAP(M, S, O)$ {{---}} блендинговое изображение, оптимизируемое относительно $O$.
Чтобы комбинировать решение задачи бесшовного наложения [[Блендинг изображений#Блендинг ПуассонаРассмотрим область $\overline{\Omega} = \{\;p \;|методом Пуассона]] с остальными ограничениями\;M_p = 0\; \}$. Заметим, авторы статьи<ref name='ZWS20'/> предлагают использовать функцию потерь что градиент $I$ в $\mathcaloverline{L}_{grad\Omega}$равен нулю. Для сохранения контуров изображений Тогда градиенты $S$ и $IB$ совпадают, и задача минимизации $\mathcal{L}_{grad}$ решается только в области вставки используется дискретный оператор Лапласа.
{{Определение|id=grad_loss_def|definition =На обоих этапах алгоритм минимизирует взвешенную сумму следующих функций потерь:* $\mathcal{L}_{gradcontent}(S, $ для сохранения содержания накладываемого изображения $I, M, O) = $.* $\displaystyle\fracmathcal{1L}_{2HWstyle}$ для переноса стиля изображения $S$ на $I$.* $\displaystyle\sum_mathcal{m=1L}^H \displaystyle\sum__{n=1hist}^W $ для стабилизации переноса стиля.* $\left[ \mathbfmathcal{DL}^2 B - \left(\mathbf{D}^2 S + \mathbf{D}^2 I\right) \right]^2__{mntv}$ {{---}} градиентная функция потерь (англ. ''Possion gradient loss'')для удаления шумов. * $H, W$ \mathcal{{---L}} высота и ширина изображений. $B = CAP(M, S, O)$ _{{---grad}} блендинговое изображение, оптимизируемое относительно $O$для сохранения контуров фона и изображения. }}
Рассмотрим область <!-- 0JAg0LXRidGRINCd0LDRgdGC0Y8g0L7Rh9C10L3RjCDQvNC40LvQsNGPIQ== -->Для подсчета $\overlinemathcal{\OmegaL} = \_{\;p \;| \;M_p = 0\; \style}$. Заметим, что градиент $I$ в $\overline{\Omega}$ равен нулю. Тогда градиенты $S$ и $B$ совпадают, и задача минимизации $\mathcal{L}_{gradcontent}$ решается только в области вставкиавторами статьи<ref name='ZWS20'>[https://openaccess.thecvf.com/content_WACV_2020/papers/Zhang_Deep_Image_Blending_WACV_2020_paper.pdf Deep Image Blending] Lingzhi Zhang, Tarmily Wen, Jianbo Shi (2020)</ref> использовалась сеть VGG-19<ref name="SZ14"/>, обученная на ImageNet<ref name="ImageNet">https://image-net.org/papers/imagenet_cvpr09.pdf J. Deng, W. Dong, R. Socher, L.-J. Li, K. Li, and L. FeiFei. Imagenet: A large-scale hierarchical image database</ref>.
=== Первый этап ===
 
<div class="tright" style="clear:none">[[Файл:Deep bl 2stage.png|thumb|none|200px|Результат после обоих этапов]]</div>
<div class="tright" style="clear:none">[[Файл:Deep bl 1stage.png|thumb|none|200px|Результат первого этапа]]</div>
 
На первом этапе изображение $I$ накладывается на фоновое изображение $S$ таким образом, чтобы были незаметны швы.
Построение начинается с белого шума $Z$, который оптимизируется в области вставки путем минимизации суммарной функции потерь $\mathcal{L}_{total}$, представленной взвешенной суммой всех функций потерь, описанных выше:
$$ \mathcal{L}_{total}(Z) = w_{grad}\mathcal{L}_{grad}(I, S, B) + w_{contcontent}\mathcal{L}_{contcontent}(I, M, Z) + w_{style}\mathcal{L}_{style}(S, B) + w_{tv}\mathcal{L}_{tv}(B) + w_{hist}\mathcal{L}_{hist}(S, B) .$$Для решения задачи минимизации авторы статьи<ref name='ZWS20' /> используют алгоритм L-BFGS<ref name="LBFGS">https://en.wikipedia.org/wiki/Limited-memory_BFGS Limited-memory BFGS - Wikipedia</ref>. Отметим, что $\mathcal{L}_{contcontent}$ зависит от маски и отвечает за сохранение содержания $I$ в области вставки.
Отличительной чертой этого этапа является использование функции потерь $\mathcal{L}_{grad}$, приближающей градиент результата к градиенту $I$ в области наложения, за счет чего достигается бесшовность. Для вычисления производных второго порядка используется фильтр Лапласа.
В результате получается подготовительное блендинг-изображение $B$:$$B_p =\begin{cases}Z_p,\; \text{если } M_p = 1 \\S_p,\; \text{иначе } \end{cases}$$.
<font size="3em">
'''fun''' $SeamlessBlending$(
<span style="display: inline-block; width: 3em">$I$, </span> <font color="green"> // Входное изображение </font> <span style="display: inline-block; width: 3em">$M$, </span> <font color="green"> // Маска </font> <span style="display: inline-block; width: 3em">$S$ </span> <font color="green"> // Стилевое изображение </font>
):
<font color="green">// Инициализируем первое приближение белым шумом </font>
$B \leftarrow CAP(M, S, Z)$
<font color="green">// Определим суммарную функцию потерь с весами слагаемых $w$</font>
$\mathcal{L}_{total}(Z) \leftarrow w_{grad}\mathcal{L}_{grad}(I, S, B) + w_{contcontent}\mathcal{L}_{contcontent}(I, M, Z) + w_{style}\mathcal{L}_{style}(S, B) + w_{tv}\mathcal{L}_{tv}(B) + w_{hist}\mathcal{L}_{hist}(S, B)$
<font color="green">// С помощью алгоритма L-BFGS ищем изображение $Z$, которое минимизирует $\mathcal{L}_{total}$ </font>
$Z \leftarrow Reconstruct(\mathcal{L}_{total}, Z)$
В отличие от предыдущего этапа, функция потерь не включает в себя $\mathcal{L}_{grad}$:
$$\mathcal{L}_{total}(O) = w_{contcontent}\mathcal{L}_{contcontent}(B, O) + w_{style}\mathcal{L}_{style}(S, O) + w_{tv}\mathcal{L}_{tv}(O) + w_{hist}\mathcal{L}_{hist}(S, O).$$
Минимизация происходит относительно результата алгоритма $O$, которой который инициализируется изображением $B$.
<font size="3em">
'''fun''' $StyleRefinement$(
<span style="display: inline-block; width: 3em">$B$, </span> <font color="green"> // Подготовительное блендинг-изображение, результат первого этапа </font> <span style="display: inline-block; width: 3em">$M$, </span> <font color="green"> // Маска </font> <span style="display: inline-block; width: 3em">$S$ </span> <font color="green"> // Стилевое изображение </font>
):
$O \leftarrow B$
<font color="green">// Определим суммарную функцию потерь с весами слагаемых $w$</font>
$\mathcal{L}_{total}(O) \leftarrow w_{cont}\mathcal{L}_{contcontent}(B, O) + w_{style}\mathcal{L}_{style}(S, O) + w_{tv}\mathcal{L}_{tv}(O) + w_{hist}\mathcal{L}_{hist}(S, O)$
<font color="green">// С помощью алгоритма L-BFGS ищем изображение $O$, которое минимизирует $\mathcal{L}_{total}$ </font>
$O \leftarrow Reconstruct(\mathcal{L}_{total}, O)$
'''return''' $O$
</font>
 
Примеры с [https://github.com/owenzlz/DeepImageBlending/tree/master/results Github авторов]:
 
{|
! После первого этапа
! После обоих этапов
|-
| [[Файл:1_first_pass.png|300px]]
| [[Файл:1_second_pass.png|300px]]
|-
| [[Файл:3_first_pass.png|300px]]
| [[Файл:3_second_pass.png|300px]]
|-
| [[Файл:5_first_pass.png|300px]]
| [[Файл:5_second_pass.png|300px]]
|}
===Детали реализации===
В статье использовались следующие значения коэффициентов:
{| class="wikitable"
! Этап
! $w_{grad}$
! $w_{contcontent}$
! $w_{style}$
! $w_{hist}$
| $10^{-6}$
|}
 <!--Для подсчета $\mathcal{L}_{style}$ используются слои $conv{1_2}conv1_2, conv{2_2}conv2_2, conv{3_3}conv3_3, conv{4_3}$ $conv4_3 VGG$-19, для $\mathcal{L}_{contcontent}$ {{---}} conv2_2.-->{| class="wikitable"|+ Коэффициенты $\alpha$ и $\beta$|-! Параметр ! conv1_2 ! conv2_2! conv3_3! conv4_3 |-! $\alpha$ | $0$conv{2_2| $1$| $0$| $0$|-! $\beta$| $1/4$| $1/4$| $1/4$| $1/4$|}$.
На обоих этапах максимальное количество итераций алгоритма L-BFGS {{---}} $1000$.
=== Примеры ===
Примеры с [[Файлhttps:МЛ блендинг пример//github.png|1000px]com/owenzlz/DeepImageBlending/tree/master/results Github авторов]:
==Ссылки==[[Файл:МЛ блендинг пример.png|800px]]
==См. также==* [[Neural_Style_Transfer|Neural Style Transfer]]* [[Сверточные_нейронные_сети | Свёрточная нейронная сеть]] ==Источники информации==* [https://en.wikipedia.org/wiki/Gramian_matrix Матрица Грама Histogram_matching Histogram matching]* Patrick Perez, Michel Gangnet, Andrew Blake (2003), [https://www.cs.jhu.edu/~misha/Fall07/Papers/Perez03.pdf Poisson Image Editing].<!--* Karen Simonyan, Andrew Zisserman (2014), [https://arxiv.org/pdf/1409.1556.pdf Very Deep Convolutional Networks for Large-Scale Image Recognition]-->* Leon A. Gatys, Alexander S. Ecker, Matthias Bethge (англ2016), [https://rn-unison.github.io/articulos/style_transfer.pdf Image Style Transfer Using Convolutional Neural Networks]<!--* Eric Risser, Pierre Wilmot, Connelly Barnes (2017), [https://arxiv.org/pdf/1701.08893.pdf Stable and Controllable Neural Texture Synthesis and Style Transfer Using Histogram Losses]--><!--* Aravindh Mahendran, Andrea Vedaldi (2015), [https://arxiv.org/pdf/1412.0035.pdf Understanding Deep Image Representations by Inverting Them]--><!--* Justin Johnson, Alexandre Alahi, Li Fei-Fei (2016), [https://arxiv.org/pdf/1603.08155.pdf Perceptual Losses for Real-Time Style Transfer and Super-Resolution]--><!--* Jing Liao, Yuan Yao, Lu Yuan, Gang Hua, Sing Bing Kang (2017), [https://arxiv.org/pdf/1705.01088.pdf Visual Attribute Transfer through Deep Image Analogy]-->* Fujun Luan, Sylvain Paris, Eli Shechtman, Kavita Bala (2018), [https://arxiv.org/pdf/1804.03189.pdf Deep Painterly Harmonization]* Lingzhi Zhang, Tarmily Wen, Jianbo Shi (2020), [https://openaccess.thecvf.com/content_WACV_2020/papers/Zhang_Deep_Image_Blending_WACV_2020_paper.pdf Deep Image Blending]
==Примечания==
 
[[Категория: Машинное обучение]]
[[Категория: Нейронные сети]]
[[Категория: Сверточные нейронные сети]]
128
правок

Навигация