[PYTHON] J'ai essayé d'extraire le dessin au trait de l'image avec Deep Learning

J'ai essayé d'extraire un dessin au trait d'une image avec Deep Learning

Quand j'ai remarqué, GW est passé en un clin d'œil. Cette année, GW a fait le tour de Tokyo (y compris certains Saitama) avec toute la famille. J'ai escaladé le Sky Tree, mais je ne pensais pas qu'il y avait autant de monde. Cela me paraissait intéressant d'y aller la nuit si je devais y aller ensuite. On dirait qu'il est en cours de dépistage.

Mise à jour du 6/11

J'ai modifié la structure du réseau et diverses choses dans l'ensemble de données pour améliorer le dessin au trait qui peut être extrait, donc je l'ai mis à jour avec son contenu.

Je veux un dessin au trait

Comme je l'ai écrit dans l'article précédent, j'ai essayé la coloration de dessin au trait avec Deep Learning, mais dans le processus, j'ai senti qu'il y avait des problèmes avec l'ensemble de données. Le dessin au trait lui-même a été créé en référence à http://qiita.com/khsk/items/6cf4bae0166e4b12b942, mais il semble y avoir des problèmes.

Eh bien, il y a quelques problèmes, mais je travaille toujours dessus car il peut être créé facilement (uniquement si OpenCV fonctionne) et à grande vitesse (OpenCV est abrégé).

Recherche pour transformer rugueux en dessin au trait

Certaines des recherches existantes sont les suivantes. http://hi.cs.waseda.ac.jp:8081/

Ceci est un article. http://hi.cs.waseda.ac.jp/~esimo/publications/SimoSerraSIGGRAPH2016.pdf

Il s'agit d'une technique pour AutoEncoder qui convertit le dessin brut en dessin au trait. Cette fois, je l'ai fait en référence à cela.

class AutoEncoder(object):
    """Define autoencoder"""

    def __init__(self):
        self.conv1 = Encoder(3, 48, 5, 5, strides=[1, 2, 2, 1], name='encoder1')
        self.conv1_f1 = Encoder(48, 128, 3, 3, name='encoder1_flat1')
        self.conv1_f2 = Encoder(128, 128, 3, 3, name='encoder1_flat2')
        self.conv2 = Encoder(128, 256, 5, 5, strides=[1, 2, 2, 1], name='encoder2')
        self.conv2_f1 = Encoder(256, 256, 3, 3, name='encoder2_flat1')
        self.conv2_f2 = Encoder(256, 256, 3, 3, name='encoder2_flat2')
        self.conv3 = Encoder(256, 256, 5, 5, strides=[1, 2, 2, 1], name='encoder3')
        self.conv3_f1 = Encoder(256, 512, 3, 3, name='encoder3_flat1')
        self.conv3_f2 = Encoder(512, 1024, 3, 3, name='encoder3_flat2')
        self.conv3_f3 = Encoder(1024, 512, 3, 3, name='encoder3_flat3')
        self.conv3_f4 = Encoder(512, 256, 3, 3, name='encoder3_flat4')

        self.bnc1 = op.BatchNormalization(name='bnc1')
        self.bnc1_f1 = op.BatchNormalization(name='bnc1_flat1')
        self.bnc1_f2 = op.BatchNormalization(name='bnc1_flat2')
        self.bnc2 = op.BatchNormalization(name='bnc2')
        self.bnc2_f1 = op.BatchNormalization(name='bnc2_flat1')
        self.bnc2_f2 = op.BatchNormalization(name='bnc2_flat2')
        self.bnc3 = op.BatchNormalization(name='bnc3')
        self.bnc3_f1 = op.BatchNormalization(name='bnc3_flat1')
        self.bnc3_f2 = op.BatchNormalization(name='bnc3_flat2')
        self.bnc3_f3 = op.BatchNormalization(name='bnc3_flat3')
        self.bnc3_f4 = op.BatchNormalization(name='bnc3_flat4')

        self.deconv1 = Decoder(256, 256, 4, 4, strides=[1, 2, 2, 1], name='decoder1')
        self.deconv1_f1 = Encoder(256, 128, 3, 3, name='decoder1_flat1')
        self.deconv1_f2 = Encoder(128, 128, 3, 3, name='decoder1_flat2')
        self.deconv2 = Decoder(128, 128, 4, 4, strides=[1, 2, 2, 1], name='decoder2')
        self.deconv2_f1 = Encoder(128, 128, 3, 3, name='decoder2_flat1')
        self.deconv2_f2 = Encoder(128, 48, 3, 3, name='decoder2_flat2')
        self.deconv3 = Decoder(48, 48, 4, 4, strides=[1, 2, 2, 1], name='decoder3')
        self.deconv3_f1 = Decoder(48, 24, 3, 3, name='decoder3_flat1')
        self.deconv3_f2 = Decoder(24, 1, 3, 3, name='decoder3_flat2')

        self.bnd1 = op.BatchNormalization(name='bnd1')
        self.bnd1_f1 = op.BatchNormalization(name='bnd1_flat1')
        self.bnd1_f2 = op.BatchNormalization(name='bnd1_flat2')
        self.bnd2 = op.BatchNormalization(name='bnd2')
        self.bnd2_f1 = op.BatchNormalization(name='bnd2_flat1')
        self.bnd2_f2 = op.BatchNormalization(name='bnd2_flat2')
        self.bnd3 = op.BatchNormalization(name='bnd3')
        self.bnd3_f1 = op.BatchNormalization(name='bnd3_flat1')


def autoencoder(images, height, width):
    """make autoencoder network"""

    AE = AutoEncoder()

    def div(v, d):
        return max(1, v // d)

    relu = tf.nn.relu
    net = relu(AE.bnc1(AE.conv1(images, [height, width])))
    net = relu(AE.bnc1_f1(AE.conv1_f1(net, [div(height, 2), div(width, 2)])))
    net = relu(AE.bnc1_f2(AE.conv1_f2(net, [div(height, 2), div(width, 2)])))
    net = relu(AE.bnc2(AE.conv2(net, [div(height, 2), div(width, 2)])))
    net = relu(AE.bnc2_f1(AE.conv2_f1(net, [div(height, 4), div(width, 4)])))
    net = relu(AE.bnc2_f2(AE.conv2_f2(net, [div(height, 4), div(width, 4)])))
    net = relu(AE.bnc3(AE.conv3(net, [div(height, 4), div(width, 4)])))
    net = relu(AE.bnc3_f1(AE.conv3_f1(net, [div(height, 8), div(width, 8)])))
    net = relu(AE.bnc3_f2(AE.conv3_f2(net, [div(height, 8), div(width, 8)])))
    net = relu(AE.bnc3_f3(AE.conv3_f3(net, [div(height, 8), div(width, 8)])))
    net = relu(AE.bnc3_f4(AE.conv3_f4(net, [div(height, 8), div(width, 8)])))
    net = relu(AE.bnd1(AE.deconv1(net, [div(height, 4), div(width, 4)])))
    net = relu(AE.bnd1_f1(AE.deconv1_f1(net, [div(height, 4), div(width, 4)])))
    net = relu(AE.bnd1_f2(AE.deconv1_f2(net, [div(height, 4), div(width, 4)])))
    net = relu(AE.bnd2(AE.deconv2(net, [div(height, 2), div(width, 2)])))
    net = relu(AE.bnd2_f1(AE.deconv2_f1(net, [div(height, 2), div(width, 2)])))
    net = relu(AE.bnd2_f2(AE.deconv2_f2(net, [div(height, 2), div(width, 2)])))
    net = relu(AE.bnd3(AE.deconv3(net, [height, width])))
    net = relu(AE.bnd3_f1(AE.deconv3_f1(net, [height, width])))

    net = tf.nn.sigmoid(AE.deconv3_f2(net, [height, width]))

    return net

AutoEncoder ressemble à ceci. Je me suis demandé si je pouvais l'obtenir d'une manière ou d'une autre. Dans l'article, il semble que l'accent soit mis sur la méthode appelée carte de perte, mais comme je ne sais pas comment faire référence à l'histogramme dans Tensorflow, cette partie est implémentée.

Je l'ai essayé

Le réseau utilisé était environ 250 000 fois avec les paramètres suivants.

J'ai abandonné la taille énorme parce que je ne pouvais pas survivre même avec 2 Go de mémoire en premier lieu. Il semble bon de le réduire une fois, de l'extraire, puis d'insérer un encodeur pour augmenter la résolution.

Image de taille raisonnable

Mikon! Je l'ai peint. Amezuku @ Recherche d'emploi

Toutes les images originales sont empruntées car je les ai peintes avec Pixiv. Cette image n'a pas de dessin au trait original, et il n'y a pas de cible de comparaison en premier lieu, alors c'est tout. Cela a pris environ 10 secondes pour cette taille et pour le GPU, donc honnêtement, je ne veux pas penser à le faire avec un processeur.

Je pense que c'est assez solide. La taille moyenne des images de l'ensemble de données est d'environ 1000 \ * 1000, ce qui est assez grand, de sorte que même les images d'une certaine taille peuvent être gérées. Cependant, malheureusement, il y a une dentelure propre à la partie inférieure ... Cela ne peut pas être dit car il y a des moments où il sort et des moments où il ne sort pas. output1.png

Taille du Thumblet

La taille est de 256 \ * 256. Pour le moment, j'inclurai également la version que j'ai retirée avec OpenCV. Ignorez le tsukkomi que 256 \ * 256 est miniature.

Image originale. À première vue, il semble qu'une ligne apparaîtra, mais ... small_origin.jpeg

Version OpenCV. Puisque toutes les belles couleurs ont été libérées, je ne peux pas nier le sentiment qu'il s'agit d'un dessin au trait ou d'une échelle de gris. small_opencv.jpeg

Cette version réseau. C'est en partie suspect (ou plutôt, la partie main est impossible à jouer), mais l'influence de l'ombre peut être assez bien ignorée, et l'expression de la partie cheveux est simple, c'est un miso avant, mais ça fait plutôt bien N'est-ce pas? Des détails trop fins tels que des volants sont écrasés par la pierre, mais il semble que cela puisse être résolu petit à petit si vous continuez à en apprendre un peu plus. small_cnn.jpeg

À propos de l'ensemble de données

L'ensemble de données utilisé pour la formation est essentiellement obtenu à partir des catégories peintes par Pixiv. La chose la plus importante dans la création d'un ensemble de données était que ** le dessin au trait et le dessin en couleur avaient le même aspect **. Si cela change, ce sera comme ne pas pouvoir apprendre en premier lieu, alors je les ai rassemblés en vérifiant chacun d'eux.

Aussi, j'ai parfois trouvé que même si le rapport hauteur / largeur était le même, il y avait une légère différence entre le dessin au trait et l'image colorée **. J'ai dû l'omettre correctement parce que l'apprentissage ne se poursuivrait pas s'il y en avait aussi.

Faiblesses

Cela dépend de la façon dont vous le peignez, mais je pense que c'est une ligne plus simple qu'OpenCV, et les détails ne sont pas tellement perdus. Cependant, en raison de la structure ou de la nature de ce que nous faisons, il y a des inconvénients, notamment le fait que nous ne pouvons rien y faire.

Fondamentalement, plutôt que de l'utiliser tel quel, je pense que ce sera plutôt un traitement basé sur cela.

Résumé

Les réseaux de génération tels que AutoEncoder sont intéressants. Je veux également relever le défi de donner des paramètres pour changer la façon dont les dessins au trait sont créés.

C'est difficile à étudier et à mettre en œuvre, mais comme les amateurs peuvent faire du Deep Learning, nous vous recommandons d'investir un peu et de l'essayer (seul ou dans le cloud).

Recommended Posts

J'ai essayé d'extraire le dessin au trait de l'image avec Deep Learning
J'ai essayé d'écrire dans un modèle de langage profondément appris
Essayez d'extraire une chaîne de caractères d'une image avec Python3
[Deep Learning from scratch] J'ai essayé d'expliquer le décrochage
J'ai essayé d'implémenter Perceptron Part 1 [Deep Learning from scratch]
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 16) J'ai essayé de créer SimpleConvNet avec Keras
Un débutant a essayé de colorier un dessin au trait avec un chainer. J'ai pu le faire.
J'ai essayé de rendre le deep learning évolutif avec Spark × Keras × Docker
[Deep Learning from scratch] J'ai essayé d'expliquer la confirmation du gradient d'une manière facile à comprendre.
J'ai essayé de couper une image fixe de la vidéo
[Apprentissage automatique] J'ai essayé de faire quelque chose comme passer des images
J'ai essayé de créer une fonction de similitude d'image avec Python + OpenCV
J'ai essayé de mettre en œuvre un apprentissage en profondeur qui n'est pas profond avec uniquement NumPy
[Deep Learning from scratch] J'ai essayé d'implémenter la couche sigmoïde et la couche Relu
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
J'ai essayé d'envoyer un e-mail de fin d'inscription depuis Gmail avec django.
J'ai essayé d'obtenir une image en grattant
J'ai essayé de détecter un objet avec M2Det!
J'ai essayé le deep learning
[Python] Deep Learning: J'ai essayé d'implémenter Deep Learning (DBN, SDA) sans utiliser de bibliothèque.
J'ai essayé d'implémenter Cifar10 avec la bibliothèque SONY Deep Learning NNabla [Nippon Hurray]
J'ai essayé de créer une API de reconnaissance d'image simple avec Fast API et Tensorflow
J'ai essayé de rendre le deep learning évolutif avec Spark × Keras × Docker 2 Multi-host edition
Je veux convertir une image en WebP avec sucette
J'ai essayé d'extraire des fonctionnalités avec SIFT d'OpenCV
J'ai essayé de détecter l'iris à partir de l'image de la caméra
Je veux escalader une montagne avec l'apprentissage par renforcement
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé de collecter des données sur un site Web avec Scrapy
J'ai essayé de créer une application OCR avec PySimpleGUI
J'ai essayé de trouver la classe alternative avec tensorflow
Introduction à l'apprentissage automatique à partir de Simple Perceptron
J'ai essayé de compresser l'image en utilisant l'apprentissage automatique
J'ai essayé de créer un environnement avec WSL + Ubuntu + VS Code dans un environnement Windows
J'ai essayé de faire une simulation de séparation de source sonore en temps réel avec l'apprentissage automatique Python
J'ai essayé de prédire les courses de chevaux en faisant tout, de la collecte de données à l'apprentissage en profondeur
J'ai essayé de créer un environnement d'apprentissage amélioré pour Othello avec Open AI gym
Traitement d'image avec Python (j'ai essayé de le binariser en art mosaïque 0 et 1)
J'ai essayé de faire de l'art créatif avec l'IA! J'ai programmé une nouveauté! (Article: Réseau Adversaire Créatif)
J'ai essayé de créer un environnement d'apprentissage automatique avec Python (Mac OS X)
J'ai essayé d'implémenter une ligne moyenne mobile de volume avec Quantx
J'ai essayé de trouver l'entropie de l'image avec python
J'ai essayé d'extraire des caractères des sous-titres (OpenCV: édition tesseract-ocr)
Essayez de créer un réseau de neurones / d'apprentissage en profondeur avec scratch
J'ai essayé d'envoyer un e-mail d'Amazon SES avec Python
J'ai essayé de créer automatiquement un rapport avec la chaîne de Markov
Créez un environnement pour "Deep Learning from scratch" avec Docker
J'ai essayé d'héberger un modèle d'apprentissage en profondeur de TensorFlow à l'aide de TensorFlow Serving
J'ai essayé de résoudre le problème d'optimisation des combinaisons avec Qiskit
J'ai essayé de commencer avec Hy ・ Définir une classe
Mayungo's Python Learning Episode 3: J'ai essayé d'imprimer des nombres
Je veux installer le package de requirements.txt avec poésie
Je souhaite envoyer un message de Python à LINE Bot
J'ai essayé d'implémenter ListNet d'apprentissage de rang avec Chainer
J'ai essayé de trier une colonne FizzBuzz aléatoire avec un tri à bulles.
J'ai capturé le projet Toho avec Deep Learning ... je le voulais.
J'ai essayé de créer un article dans Wiki.js avec SQL Alchemy
J'ai créé un serveur avec socket Python et ssl et j'ai essayé d'y accéder depuis le navigateur