kshitizrimal / deepStyle

Oct 19, 2021
admin

Il s’agit d’une implémentation TensorFlow de plusieurs techniques décrites dans les articles :

  • Transfert de style d’image à l’aide de réseaux neuronaux convolutifspar Leon A. Gatys, Alexander S. Ecker, Matthias Bethge
  • Transfert de style artistique pour les vidéospar Manuel Ruder, Alexey Dosovitskiy, Thomas Brox
  • Préservation de la couleur dans le transfert de style artistique neuronalpar Leon A. Gatys, Matthias Bethge, Aaron Hertzmann, Eli Shechtman

De plus, des techniques sont présentées pour la segmentation sémantique et le transfert de style multiple.

L’algorithme de style neuronal synthétise un pastiche en séparant et en combinant le contenu d’une image avec le style d’une autre image en utilisant des réseaux neuronaux convolutifs (CNN). Voici un exemple de transfert du style artistique de La Nuit étoilée sur une photographie d’un lion africain :

Transférer le style de diverses œuvres d’art sur la même image de contenu produit des résultats qualitativement convaincants :

Nous reproduisons ici la figure 3 du premier article, qui rend une photographie du Neckarfront à Tübingen, en Allemagne, dans le style de 5 peintures iconiques différentes Le naufrage du Minotaure, La nuit étoilée, Composition VII, Le cri, Nu assis :

Compromis contenu / style

Le poids relatif du style et du contenu peut être contrôlé.

Voici un rendu avec un poids de style croissant appliqué à Red Canna:

Images de style multiples

Plusieurs images de style peuvent être utilisées pour mélanger plusieurs styles artistiques.

Rangée supérieure (de gauche à droite) : La Nuit étoilée + Le Cri, Le Cri + Composition VII, Nu assis + Composition VII
Rangée du bas (de gauche à droite) : Nu assis + La nuit étoilée, Oversoul + Fraîcheur du froid, David Bowie + Crâne

Interpolation de style

Lorsqu’on utilise plusieurs images de style, le degré de mélange entre les images peut être contrôlé.

Rangée supérieure (de gauche à droite) : image de contenu, .2 La nuit étoilée + .8 Le cri, .8 La nuit étoilée + .2 Le cri
La rangée du bas (de gauche à droite) : .2 Oversoul + .8 Fraîcheur du froid, .5 Oversoul + .5 Fraîcheur du froid, .8 Oversoul + .2 Fraîcheur du froid

Style de transfert mais pas la couleur

Le schéma de couleurs de l’image originale peut être préservé en incluant l’indicateur --original_colors. Les couleurs sont transférées en utilisant soit les espaces couleur YUV, YCrCb, CIE L*a*b* ou CIE L*u*v*.

Vous reproduisez ici la figure 1 et la figure 2 du troisième article en utilisant le transfert de luminance uniquement :

De gauche à droite : image de contenu, image stylisée, image stylisée avec les couleurs originales de l’image de contenu

Textures

L’algorithme n’est pas limité aux styles de peinture artistique. Il peut également être appliqué à des textures photographiques pour créer des images pareidoliques.

Segmentation

Le style peut être transféré à des segmentations sémantiques dans l’image de contenu.

Des styles multiples peuvent être transférés au premier plan et à l’arrière-plan de l’image de contenu.

De gauche à droite : image de contenu, style de premier plan, style d’arrière-plan, masque de premier plan, masque d’arrière-plan, image stylisée

Vidéo

Des animations peuvent être rendues en appliquant l’algorithme à chaque image source. Pour obtenir les meilleurs résultats, la descente de gradient est initialisée avec l’image stylisée précédente déformée vers l’image actuelle selon le flux optique entre la paire d’images. Des fonctions de perte pour la cohérence temporelle sont utilisées pour pénaliser les pixels excluant les régions désoccultées et les limites de mouvement.


Ligne supérieure (de gauche à droite) : images sources, flux optique de vérité du sol visualisé
Ligne inférieure (de gauche à droite) : régions exclues et frontières de mouvement, images stylisées

Initialisation de la descente de gradient

L’initialisation de la descente de gradient est contrôlée en utilisant --init_img_type pour les images uniques et --init_frame_type ou --first_frame_type pour les trames vidéo. Le bruit blanc permet de générer un nombre arbitraire d’images distinctes. Alors que l’initialisation avec une image fixe converge toujours vers le même résultat.

Voici la figure 6 du premier article:

Ligne supérieure (de gauche à droite) : Initialisée avec l’image de contenu, l’image de style, le bruit blanc (RNG seed 1)
La rangée du bas (de gauche à droite) : Initialisée avec le bruit blanc (RNG seeds 2, 3, 4)

Représentations des couches

Les complexités des caractéristiques et les tailles des champs réceptifs augmentent vers le bas de l’hériarchie CNN.

Nous reproduisons ici la figure 3 de l’article original :

.

.

.

1 x 10^-5 1 x 10^-4 1 x 10^-3 1 x 10^-2
conv1_1
conv2_1
conv3_1
conv4_1
conv5_1

Lignes : sous-ensembles croissants de couches CNN ; c’est-à-dire.Par exemple, ‘conv4_1’ signifie utiliser ‘conv1_1’, ‘conv2_1’, ‘conv3_1’, ‘conv4_1’.
Colonnes : rapport alpha/beta de la reconstruction du contenu et du style (voir le compromis contenu / style).

Setup

Dépendances:

  • tensorflow
  • opencv

Dépendances optionnelles (mais recommandées):

  • CUDA 7.5+
  • cuDNN 5.0+

Après avoir installé les dépendances:

  • Téléchargez les poids du modèle VGG-19 (voir la section « Modèles VGG-VD du projet Very Deep Convolutional Networks for Large-Scale Visual Recognition »). Plus d’infos sur le réseau VGG-19 peuvent être trouvées ici.
  • Après le téléchargement, copiez le fichier des poids imagenet-vgg-verydeep-19.mat dans le répertoire du projet.

Utilisation

Utilisation de base

Image unique

  1. Copie 1 image de contenu dans le répertoire de contenu d’image par défaut ./image_input
  2. Copie 1 ou plusieurs images de style dans le répertoire de style par défaut ./styles
  3. Exécutez la commande :
bash stylize_image.sh <path_to_content_image> <path_to_style_image>

Exemple:

bash stylize_image.sh ./image_input/lion.jpg ./styles/kandinsky.jpg

Note : les formats d’image pris en charge comprennent : .png, .jpg, .ppm, .pgm

Note : Les chemins vers les images ne doivent pas contenir le caractère ~ pour représenter votre répertoire personnel ; vous devez plutôt utiliser un chemin relatif ou le chemin absolu.

Images vidéo

  1. Copier 1 vidéo de contenu dans le répertoire de contenu vidéo par défaut ./video_input
  2. Copier 1 ou plusieurs images de style dans le répertoire de style par défaut ./styles
  3. Exécuter la commande:
bash stylize_video.sh <path_to_video> <path_to_style_image>

Exemple:

bash stylize_video.sh ./video_input/video.mp4 ./styles/kandinsky.jpg

Note : Les formats vidéo pris en charge comprennent : .mp4, .mov, .mkv

Utilisation avancée

Image unique ou trames vidéo

  1. Copier des images de contenu dans le répertoire de contenu d’image par défaut ./image_input ou copier des trames vidéo dans le répertoire de contenu vidéo par défaut ./video_input
  2. Copier 1 ou plusieurs images de style dans le répertoire de style par défaut ./styles
  3. Exécuter la commande avec des arguments spécifiques :
python neural_style.py <arguments>

Exemple (Image unique):

python neural_style.py --content_img golden_gate.jpg \ --style_imgs starry-night.jpg \ --max_size 1000 \ --max_iterations 100 \ --original_colors \ --device /cpu:0 \ --verbose;

Pour utiliser plusieurs images de style, passez une liste séparée par des espaces des noms d’images et des poids d’images comme ceci:

--style_imgs starry_night.jpg the_scream.jpg --style_imgs_weights 0.5 0.5

Exemple (Images vidéo):

python neural_style.py --video \ --video_input_dir ./video_input/my_video_frames \ --style_imgs starry-night.jpg \ --content_weight 5 \ --style_weight 1000 \ --temporal_weight 1000 \ --start_frame 1 \ --end_frame 50 \ --max_size 1024 \ --first_frame_iterations 3000 \ --verbose;

Note : Lorsque vous utilisez --init_frame_type prev_warp, vous devez avoir préalablement calculé le flux optique arrière et avant entre les images. Voir ./video_input/make-opt-flow.sh et ./video_input/run-deepflow.sh

Arguments

  • --content_img : Nom de fichier de l’image de contenu. Exemple : lion.jpg
  • --content_img_dir : Chemin de répertoire relatif ou absolu vers l’image de contenu. Par défaut : ./image_input
  • --style_imgs : Noms de fichiers des images de style. Pour utiliser plusieurs images de style, passez une liste séparée par des espaces. Exemple : --style_imgs starry-night.jpg
  • --style_imgs_weights : Les poids de mélange pour chaque image de style. Par défaut : 1.0 (suppose une seule image de style)
  • --style_imgs_dir : Chemin de répertoire relatif ou absolu vers les images de style. Par défaut : ./styles
  • --init_img_type : Image utilisée pour initialiser le réseau. Choix : content, random, style. Par défaut : content
  • --max_size : Largeur ou hauteur maximale des images d’entrée. Par défaut : 512
  • --content_weight : Poids pour la fonction de perte de contenu. Par défaut : 5e0
  • --style_weight : Poids pour la fonction de perte de style. Par défaut : 1e4
  • --tv_weight : Poids pour la fonction de perte variationnelle totale. Par défaut : 1e-3
  • --temporal_weight : Poids pour la fonction de perte temporelle. Par défaut : 2e2
  • --content_layers : Noms de couches VGG-19 séparés par l’espace utilisés pour l’image de contenu. Par défaut : conv4_2
  • --style_layers : Noms de couches VGG-19 séparés par l’espace utilisés pour l’image de style. Par défaut : relu1_1 relu2_1 relu3_1 relu4_1 relu5_1
  • --content_layer_weights : Poids séparés dans l’espace de chaque couche de contenu à la perte de contenu. Par défaut : 1.0
  • --style_layer_weights : Poids séparés par l’espace de chaque couche de style à la perte. Par défaut : 0.2 0.2 0.2 0.2 0.2
  • --original_colors : Drapeau booléen indiquant si le style est transféré mais pas les couleurs.
  • --color_convert_type : Espaces de couleur (YUV, YCrCb, CIE L*u*v*, CIE L*a*b*) pour la conversion de la correspondance de luminance aux couleurs d’origine. Choix possibles : yuv, ycrcb, luv, lab. Par défaut : yuv
  • --style_mask : drapeau booléen indiquant si le style est transféré aux régions masquées.
  • --style_mask_imgs : Noms de fichiers des images de masque de style (exemple : face_mask.png). Pour utiliser plusieurs images de masque de style, passez une liste séparée par des espaces. Exemple : --style_mask_imgs face_mask.png face_mask_inv.png
  • --noise_ratio : Valeur d’interpolation entre l’image de contenu et l’image de bruit si le réseau est initialisé avec random. Par défaut : 1.0
  • --seed : Semence pour le générateur de nombres aléatoires. Par défaut : 0
  • --model_weights : Poids et biais du réseau VGG-19. A télécharger ici. Défaut:imagenet-vgg-verydeep-19.mat
  • --pooling_type : Type de pooling dans le réseau de neurones convolutifs. Choix : avg, max. Par défaut : avg
  • --device : Périphérique GPU ou CPU. Le mode GPU est fortement recommandé mais nécessite NVIDIA CUDA. Choix : /gpu:0 /cpu:0. Par défaut : /gpu:0
  • --img_output_dir : Répertoire dans lequel écrire la sortie. Par défaut : ./image_output
  • --img_name : Nom de fichier de l’image de sortie. Par défaut : result
  • --verbose : Drapeau booléen indiquant si les déclarations doivent être imprimées sur la console.

Arguments d’optimisation

  • --optimizer : Optimiseur de minimisation des pertes. L-BFGS donne de meilleurs résultats. Adam utilise moins de mémoire. Choix : lbfgs, adam. Par défaut : lbfgs
  • --learning_rate : Paramètre de taux d’apprentissage pour l’optimiseur Adam. Par défaut : 1e0

  • --max_iterations : Nombre maximal d’itérations pour l’optimiseur Adam ou L-BFGS. Par défaut : 1000
  • --print_iterations : Nombre d’itérations entre les instructions d’impression de l’optimiseur. Par défaut : 50
  • --content_loss_function : Différentes constantes K dans la fonction de perte de contenu. Choix : 1, 2, 3. Par défaut : 1

Arguments de la trame vidéo

  • --video : drapeau booléen indiquant si l’utilisateur est en train de créer une vidéo.
  • --start_frame : Numéro de la première image. Par défaut : 1
  • --end_frame : Numéro de la dernière image. Par défaut : 1
  • --first_frame_type : Image utilisée pour initialiser le réseau pendant le rendu de la première trame. Choix : content, random, style. Par défaut : random
  • --init_frame_type : Image utilisée pour initialiser le réseau lors de chaque rendu après la première trame. Choix : prev_warped, prev, content, random, style. Par défaut : prev_warped
  • --video_input_dir : Chemin de répertoire relatif ou absolu vers les cadres d’entrée. Par défaut : ./video_input
  • --video_output_dir : Chemin de répertoire relatif ou absolu vers lequel écrire les trames de sortie. Par défaut : ./video_output
  • --content_frame_frmt : Chaîne de format des trames d’entrée. Par défaut : frame_{}.png
  • --backward_optical_flow_frmt : Chaîne de format des fichiers de flux optiques en retour. Par défaut : backward_{}_{}.flo
  • --forward_optical_flow_frmt : Chaîne de format des fichiers de flux optique avant. Par défaut : forward_{}_{}.flo
  • --content_weights_frmt : Chaîne de format des fichiers de cohérence de flux optique. Par défaut : reliable_{}_{}.txt
  • --prev_frame_indices : Images précédentes à considérer pour la cohérence temporelle à long terme. Par défaut : 1
  • --first_frame_iterations : Nombre maximal d’itérations de l’optimiseur de la première trame. Par défaut : 2000
  • --frame_iterations : Nombre maximal d’itérations de l’optimiseur pour chaque trame après la première trame. Par défaut : 800

Questions et Errata

Envoyez vos questions ou problèmes:

Mémoire

Par défaut, neural-style-tf utilise le backend GPU NVIDIA cuDNN pour les convolutions et L-BFGS pour l’optimisation.Ceux-ci produisent des résultats meilleurs et plus rapides, mais peuvent consommer beaucoup de mémoire. Vous pouvez réduire l’utilisation de la mémoire avec les éléments suivants :

  • Utiliser Adam : Ajoutez l’indicateur --optimizer adam pour utiliser Adam au lieu de L-BFGS. Cela devrait réduire de manière significative l’utilisation de la mémoire, mais nécessitera le réglage d’autres paramètres pour obtenir de bons résultats ; en particulier, vous devriez expérimenter avec différentes valeurs de --learning_rate, --content_weight, --style_weight
  • Réduire la taille de l’image : Vous pouvez réduire la taille de l’image générée avec l’argument --max_size.

Détails de mise en œuvre

Toutes les images ont été rendues sur une machine avec :

  • CPU : Intel Core i7-6800K @ 3,40GHz × 12
  • GPU : NVIDIA GeForce GTX 1080/PCIe/SSE2
  • SEG : Linux Ubuntu 16.04.1 LTS 64-bit
  • CUDA : 8.0
  • python : 2.7.12
  • tensorflow : 0.10.0rc
  • opencv : 2.4.9.1

Remerciements

L’implémentation est basée sur les projets:

  • Implémentation de Torch (Lua) ‘neural-style’ par jcjohnson
  • Implémentation de Torch (Lua) ‘artistic-videos’ par manuelruder

Les images vidéo sources ont été obtenues à partir de :

  • MPI Sintel Flow Dataset

Des images artistiques ont été créées par les artistes modernes :

  • Alex Grey
  • Minjae Lee
  • Leonid Afremov
  • Françoise Nielly
  • James Jean
  • Ben Giles
  • Callie Fink
  • H.R. Giger
  • Voka

Les images artistiques ont été créées par les artistes historiques populaires :

  • Vincent Van Gogh
  • Wassily Kandinsky
  • Georgia O’Keeffe
  • Jean-Michel Basquiat
  • Édouard Manet
  • Pablo Picasso
  • Joseph Mallord William Turner
  • Frida Kahlo

Les scripts shell Bash pour les tests ont été créés par mon frère Sheldon Smith.

Citation

Si vous trouvez ce code utile pour votre recherche, veuillez citer :

@misc{Smith2016, author = {Smith, Cameron}, title = {neural-style-tf}, year = {2016}, publisher = {GitHub}, journal = {GitHub repository}, howpublished = {\url{https://github.com/cysmith/neural-style-tf}},}

.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.