Изменения

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

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

346 байт добавлено, 18:00, 7 января 2021
Дописан второй проход
'''for''' $j \in [1 : M_l]$:
'''if''' $j \in Resize(Mask, l)$: <font color="green"> // рассматриваем патчи только внутри маски, которую нужно масштабираовать в соответсвии с размером слоя $l$ </font>
$pP_l(j) \leftarrow NearestNeighborIndex(F[I], j, F[S])$ $P_l \leftarrow MakeStyleMapping(p)$ <font color="green"> // Делаем стилевой маппинг для слоя $l$ с помощью функции $p(j)$ </font>
'''return''' $P$
</font>
$\mathcal{L}_1(I, S, O, P) = \mathcal{L}^{\alpha}_{content}(I, O) + w_{style}\mathcal{L}^{\beta}_{style}(S, O, P)$, где $w_{style}$ {{---}} вес стилевой функции потерь}}
* '''TODO''' Figure 2b , 5c (результаты после первого прохода)
===Второй проход===
<div style="font-size:130%; line-height: 3em;">
Второй проход делает более качественную гармонизацию после первого прохода. Здесь мы будем использовать более сложный алгоритм <code>ConsistentMapping</code> построения стилевого маппинга и более сложную функцию потерь. Суть этого алгоритма в том, чтобы найти стилевой мапинг на некотором слое $l_{ref}$ и перенести этот маппинг на остальные слои. Также, мы будем предпочитать маппинги, в которых смежные патчи в $F_l[S]$ остаются смежными после мапинга, чтобы обеспечить пространсвенную согласованность (видимо таким образом мы хотим переносить сложные текстуры более качественно, например мазки кистью).
</div> <pre stylefont size="font-size:130%; line-height: 2em;3em"> '''fun''' ConsistentMapping( $F[I]$, <font color="green"> // Выходы слоёв после входного изображения </font> $Mask$, <font color="green"> // Маска </font> $F[S]$ <font color="green"> // Выходы слоёв после стилевого изображения </font> ): <font color="green">// Сначала посчитаем маппинг как в IndependentMapping только для слоя $l_{ref}$ </font> '''for''' $j \in [1 : M_{l_{ref}}]$: '''if''' $j \in Resize(Mask, l_{ref})$: $p_0P_0(j) \leftarrow NearestNeighborIndex(F[I], j, F[S])$ <font color="green">// Далее обеспечиваем пространсвенную согласованность </font> '''for''' $j \in [1 : M_{l_{ref}}]$: '''if''' $j \in Resize(Mask, l_{ref})$: $q \leftarrow P_0(j)$ <font color="green">// Инициализируем множество кандидатов на новый маппинг </font> $CSet \leftarrow \{q\}$ <font color="green">// Перебираем все смежные патчи </font> '''for''' $o \in {N, NE, E, SE, S, SW, W, NW}$: <font color="green">// Добавляем в кандидаты патч, сосед которого является маппингом для нашего соседа в соответсвующем направлении </font> $CSet \leftarrow CSet \cup \{P_0(j + o) - o\}$ <font color="green">// Среди всех кандидатов выбираем тот, который ближе всего к маппингам наших соседей </font> $P_{l_{ref}}(j) \leftarrow argmin_{c \in CSet}\displaystyle\sum_o \|(F_{l_{ref}}[S]_c - F_{l_{ref}}[S]_{P_0(j + o)}\|^2$ <font color="green">// Теперь нужно перенести маппинг для $l_{ref}$ на остальные слои </font> '''for''' $l \in [1 : L] \setminus \{l_{ref}\}$: '''for''' $j \in [1 : M_l]$: '''if''' $j \in Resize(Mask, l)$: <font color="green">// Вычисляем позицию $j'$ на слое $l_{ref}$ соответствующую позиции $j$ на слое $l$</font> $j' \leftarrow ChangeResolution(l, l_{ref}, j)$ <font color="green">// Берём маппинг для позиции $j'$</font> $q \leftarrow P_{l_{ref}}(j')$ <font color="green">// Переносим позицию $q$ обратно на слой $l$</font> $P_l(j) \leftarrow ChangeResolution(l_{ref}, l, q)$ '''return''' P</font>
<font color="green">// Далее обеспечиваем пространсвенную согласованность </font> '''for''' $j \in [1 : M_{l_{ref}}]$: '''if''' $j \in Resize(Mask, l_{ref})$: $q \leftarrow p_0(j)$ $CSet \leftarrow \{q\}$ <font color="green">// Инициализируем множество кандидатов на новый маппинг </font> '''for''' $o \in {N, NE, E, SE, S, SW, W, NW}$: <font color="green">// Перебираем все смежные патчи </font> $CSet \leftarrow CSet \cup \{p_0(j + o) - o\}$ <font color="green">// Добавляем в кандидаты патчПри вычислении стилевого маппинга появляется очень много дублирующихся векторов, сосед которого является маппингом для нашего соседа в соответсвующем направлении </font> что даёт не очень хорошие результаты. Поэтому при вычислении матрицы Грама выкинем повторяющиеся векторы. Назовём эту функцию потерь $p(j) \leftarrow argmin_{c \in CSet}\displaystyle\sum_o \|(F_{l_mathcal{ref}L}[S]_c - F_{l_{ref}}[S]_{p_0(j + o)s1}\|^2$ P := MakeStyleMapping(p) <font color="green"> // Делаем стилевой маппинг с помощью функции p(j) </font> '''return''' P</pre>.
{{Определение
|definition =
$\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)$, где $w_{style}$, $w_{hist}$, $w_{tv}$ {{---}} веса соответсвующих функций потерь}}
 
*'''TODO''' figure 5f (результаты с $\mathcal{L}_{style}$ вместо $\mathcal{L}_{s1}$), 5d (результаты только после второго прохода)
===Итоговый алгоритм===
<font color="green"> // Грубый проход алгоритма. Каждый слой рассматривается отдельно при построении стилевого маппинга. </font>
$I'$ := SinglePassHarmonization($I$, $M$, $S$, IndependentMapping, $\mathcal{L}_1$)
<font color="green"> // Улучшение результата. Стилевой маппинг строится консистентно для всех слоёв. </font> $O$ := SinglePassHarmonization($I'$, $M$, $S$, ConsistentMapping, $\mathcal{L}_2$)=Глубокий блендинг== '''return''' $O$kekkekek
'''fun''' SinglePassHarmonization(
$I$, <font color="green"> // Входное изображение </font>
$M$, <font color="green"> // Маска </font>
$S$, <font color="green"> // Стилевое изображение </font>
$\pi$, <font color="green"> // Алгоритм построения стилевого маппинга </font>
$\mathcal{L}$ <font color="green"> // Функция потерь </font>
):
$F[I]$ := ComputeNeuralActivations($I$)
$F[S]$ := ComputeNeuralActivations($S$)
$P$ := $\pi(F[I], M, F[S])$
$O$ := Reconstruct($I$, $M$, $S$, $P$, $\mathcal{L}$)
'''return''' $O$
==Глубокий блендинг==
==Ссылки==
58
правок

Навигация