[PYTHON] Ich habe versucht, AI die richtige Frau der Braut beurteilen zu lassen, die in fünf gleiche Teile geteilt ist

Einführung

download.jpg

Es ist keine Übertreibung zu sagen, dass die Qualität des Liebesreises durch das Ende bestimmt wird. Und es gibt viele verschiedene Enden für Liebesreis. Harlem Ende, das keine bestimmte Person wählt. Multi-End, das das Ende für jede Heldin vorbereitet. Ein individuelles Ziel, das nur mit einer bestimmten Person erfüllt wird. Es ist eine Liebeskomödie, in der sich die Fans immer mit jedem Ende streiten, aber ich denke, es ist das individuelle Ende, das am verwirrendsten ist.

Unter ihnen ist der verwirrendste Liebesreis der letzten Zeit über das Ende, ja, "Bride of Five Equals" </ b>.

Das Ende dieser Arbeit soll das Yotsuba-Ende sein. Die Täuschung, ob sie mit anderen Heldinnen enden soll, muss jedoch eine Art Genuss von Liebesreis sein.

In diesem Artikel wird die KI nach dem Erlernen der Bilder der ersten Animationsphase dazu gebracht, die richtige Frau zu beurteilen, und ich denke ein wenig über die Möglichkeit nach, mit anderen Heldinnen zu enden.

Was du getan hast

Die Frau, die in der Hochzeitszeremonie der ersten Phase der Animation auftrat, wurde als reguläre Ehefrau angesehen, und die reguläre Ehefrau wurde anhand der Mehrklassenklassifikation von Quintuplets und anderen Bildern beurteilt. Keras wird als Framework für maschinelles Lernen verwendet. Außerdem müssen alle Lernbilder diejenigen der ersten Animationsperiode sein, und die zu beurteilenden Bilder müssen wie folgt sein.

0_5.png

Übrigens dränge ich Sanku, also hoffe ich, dass ich mein Bestes geben und mich für Sanku entscheiden werde.

Umgebung

Python : 3.9.0 conda version : 4.9.1 CPU : Intel(R) Core(TM)i5-6500 GPU : Intel(R) HD Graphics 530 keras : 2.3.1

Implementierungsverfahren

  1. Bildersammlung
  2. Gesichtsbildextraktion
  3. Beschriftung
  4. Datenklassifizierung
  5. Datenauffüllung li>
  6. Modelllernen
  7. Positives Ehefrauenurteil

    1. Sammlung von Bildern

    Erstens ist die Sammlung von Bildern. Es scheint, dass Sie opencv verwenden können, um ein Bild automatisch aufzunehmen, indem Sie einen Frame aus einem Video angeben. Da jedoch kein Video gespeichert wurde, habe ich mich entschlossen, die Animation dieses Mal aufzunehmen. Als Methode habe ich ein Programm erstellt, das alle 5 Sekunden erfasst, während eine Animationsperiode getropft wird. Wählen Sie pyautogui als Modul. Dieses Modul ist sehr nützlich, da es verschiedene andere GUI-Vorgänge automatisiert.

    capture.py

    
    
    import os
    import pyautogui
    import time
    
    start = time.time()
    
    for l in range(1,13):
        for i in range(275):
            im = pyautogui.screenshot('./capture_data/' + str(l) +'_'+ str(i) + '.png', region=(1050,50,800,450))
            time.sleep(5)
    
    end = time.time()
    print('result time is :', end - start)
    
    

    In meinem Fall floss die Animation auf dem oberen rechten Bildschirm des Desktops, der in vier Teile unterteilt war. Es handelt sich also um ein Programm, das region = (1050,50,800,450) und oben rechts auf dem Desktop erfasst. Über einen Zeitraum von etwa 5 Stunden wurden insgesamt 3300 Bilder aufgenommen. Das aufgenommene Bild sieht so aus.

    capture01.png

    Ich kann die Bestellung von gegrilltem Fleisch ohne gegrilltes Fleisch immer noch nicht vergessen. Übrigens ist beim Aufnehmen aus einem Video durch Angabe eines Frames Folgendes hilfreich.

    Beim Aufnehmen aus einem Video

    2. Extraktion des Gesichtsbildes

    Als nächstes wird das Gesichtsbild aus dem von opencv aufgenommenen Bild extrahiert. Als Kaskadenklassifikator für Gesichtsbilder haben wir hier verwendet, das für Anime-Bilder bekannt ist. Kopieren Sie diese XML-Datei in Ihr Arbeitsverzeichnis, erkennen Sie das Gesicht aus dem zuvor aufgenommenen Bild und extrahieren Sie es. Zur Vereinfachung der Verwendung von VGG16 als Modell für vertiefendes Lernen ist die Anzahl der Pixel auf 64 x 64 Pixel festgelegt.

    face_cut.py

    
    
    import cv2
    
    def face_cut(img_path, save_path):
        img = cv2.imread(img_path)
        cascade = cv2.CascadeClassifier('lbpcascade_animeface.xml')![face_cut01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208060/e1ce4d3c-113c-f329-ee3a-71a47e7a462c.png)
    
        facerect = cascade.detectMultiScale(img)
        for i, (x,y,w,h) in enumerate(facerect):
            face_img = img[y:y+h, x:x+w]
            face_img = cv2.resize(face_img, (64, 64))
            cv2.imwrite(save_path, face_img)
    
    for l in range(1,13):
        for i in range(275):
            face_cut('capture_data/'+str(l)+'_'+str(i)+'.png', 'cut_data/'+str(l)+'_'+str(i)+'.png')
    
    
    

    Die extrahierten Bilder sind wie folgt. Es scheint, dass sogar die Tante des Schulessens vorerst extrahiert wird. Von den 3300 aufgenommenen Bildern wurden 1365 im Gesicht erkannt. Mit anderen Worten, es war möglich, das Gesicht mit etwas mehr als 1/3 der Gesamtmenge zu extrahieren.

    face_cut01.png

    3. Kennzeichnung

    Hier werden 1365 Blätter manuell in die Verzeichnisse jeder Heldin sortiert. Es dauerte nicht lange, bis es ungefähr 1365 war, aber wenn die Anzahl der Bilder in der Größenordnung von 10.000 liegt, scheint es unwahrscheinlich.

    tesagyou.py

    
    
    #Gib dein Bestes! !! !!
    
    

    Die Sortierergebnisse sind in der folgenden Tabelle aufgeführt.

    Einstufung Anzahl der Blätter
    Ichihana 206
    Nino 168
    Sanku 152
    Yotsuba 172
    Kann 204
    Andere 463

    Ichihana übernahm die Führung mit 206 Blättern, und May jagte nach einem knappen Vorsprung. Es gibt einen Unterschied von 54 zwischen der maximalen Anzahl von Ichihana und der minimalen Anzahl von Sanku, und es kann notwendig sein, die Anzahl der Lernblätter gleich zu machen, wenn Strenge zu erwarten ist, aber diesmal spielt es keine Rolle, wie streng sie ist, also fahren Sie fort, wie sie ist Ich werde das machen.

    4. Datenklassifizierung

    Hier wird das vorherige Gesichtsbild in Pandas konvertiert und mit 0 bis 5 beschriftet. Das Verhältnis der Anzahl der Züge und Tests betrug 8: 2.

    split.py

    
    
    # split.py
    
    import numpy as np
    import glob
    import cv2
    from keras.utils.np_utils import to_categorical
    import pandas as pd
    import matplotlib.pyplot as plt
    
    names = ['other', 'ichika', 'nino', 'miku', 'yotsuba', 'itsuki']
    img_list = []
    label_list = []
    
    # append index
    for index, name in enumerate(names):
        face_img = glob.glob('data/'+name+'/*.png')
        for face in face_img:
            # imread RGB
            a = cv2.imread(face, 1)
            b = np.expand_dims(a, axis=0)
            img_list.append(b)
            label_list.append(index)
    
    # convert pandas
    X_pd = pd.Series(img_list)
    y_pd = pd.Series(label_list)
    
    # merge
    Xy_pd = pd.concat([X_pd, y_pd], axis=1)
    # shuffle
    sf_Xy = Xy_pd.sample(frac=1)
    #Nach dem Mischen als Liste erneut abrufen
    img_list = sf_Xy[0].values
    label_list = sf_Xy[1].values
    #Tupeln und kombinieren
    X = np.r_[tuple(img_list)]
    # convert binary
    Y = to_categorical(label_list)
    
    train_rate = 0.8
    
    train_n = int(len(X) * train_rate)
    train_X = X[:train_n]
    test_X = X[train_n:]
    train_y = Y[:train_n][:]
    test_y = Y[train_n:][:]
    
    

    5. Aufgeblasene Daten

    Als nächstes hatte ich keine Lust mehr als 1000 Blatt zu lernen, also habe ich nur die Zugbilder aufgefüllt. Als aufgeblasene Gegenstände wurden Links-Rechts-Inversion, Unschärfe und γ-Umwandlung durchgeführt, und das Zugbild wurde 2 ** 3-mal aufgeblasen. Damit beträgt die Gesamtzahl etwa 10.000.

    • Der Einfachheit halber sind die Codes getrennt, aber die Codes 4 und 5 sind tatsächlich eine Datei.

    split.py

    
    
    ## define scratch_functions
    
    #Horizontal spiegeln
    def flip(img):
        flip_img = cv2.flip(img, 1)
        return flip_img
    
    #Verwischen
    def blur(img):
        blur_img = cv2.GaussianBlur(img, (5,5), 0)
        return blur_img
    
    #γ-Umwandlung
    def gamma(img):
        gamma = 0.75
        LUT_G = np.arange(256, dtype = 'uint8')
        for i in range(256):
            LUT_G[i] = 255 * pow(float(i) / 255, 1.0 / gamma)
        gamma_img = cv2.LUT(img, LUT_G)
        return gamma_img
    
    total_img = []
    for x in train_X:
        imgs = [x]
        # concat list
        imgs.extend(list(map(flip, imgs)))
        imgs.extend(list(map(blur, imgs)))
        imgs.extend(list(map(gamma, imgs)))
        total_img.extend(imgs)
    
    # add dims to total_img
    img_expand = list(map(lambda x:np.expand_dims(x, axis=0), total_img))
    #Tupeln und kombinieren
    train_X_scratch = np.r_[tuple(img_expand)]
    
    labels = []
    for label in range(len(train_y)):
        lbl = []
        for i in range(2**3):
            lbl.append(train_y[label, :])
        labels.extend(lbl)
    
    label_expand = list(map(lambda x:np.expand_dims(x, axis=0), labels))
    train_y_scratch = np.r_[tuple(label_expand)]
    
    

    6. Modelltraining

    Schließlich wird das Modell anhand des vorbereiteten Bildes trainiert. VGG16 wurde als Modell für tiefes Lernen ausgewählt, obwohl es keine besondere Bedeutung hat. Um ehrlich zu sein, war es überraschend, dass das Lernen ungefähr einen halben Tag dauerte, da die Anzahl der Epochen auf 100 eingestellt war und die GPU so verwirrt war.

    model.py

    
    
    from keras.applications import VGG16
    from keras.models import Model, Sequential
    from keras.layers import Dense, Activation, Flatten, Input, Dropout
    from keras import optimizers
    import matplotlib.pyplot as plt
    from split import *
    
    # define input_tensor
    input_tensor = Input(shape=(64,64,3))
    vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)
    
    top_model = Sequential()
    top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
    top_model.add(Dense(64, activation='sigmoid'))
    top_model.add(Dropout(0.5))
    top_model.add(Dense(32, activation='sigmoid'))
    top_model.add(Dropout(0.5))
    top_model.add(Dense(6, activation='softmax'))
    
    model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))
    
    # vgg_model apply to 15layers
    for layer in model.layers[:15]:
        layer.trainable = False
    
    # compile
    model.compile(loss='categorical_crossentropy', optimizer=optimizers.SGD(lr=1e-4, momentum=0.9), metrics=['accuracy'])
    history = model.fit(train_X_scratch, train_y_scratch, epochs=100, batch_size=32, validation_data=(test_X, test_y))
    score = model.evaluate(test_X, test_y, verbose=0)
    print(score)
    
    # save model
    model.save('my_model.h5')
    
    # plot acc, val_acc
    plt.plot(history.history['acc'], label='acc', ls='-')
    plt.plot(history.history['val_acc'], label='val_acc', ls='-')
    plt.ylabel('accuracy')
    plt.xlabel('epoch')
    plt.legend(loc='best')
    plt.show()
    
    

    Die Genauigkeit ist nicht sehr gut, aber ein Modell zur Klassifizierung der fünf Heldinnen wurde fertiggestellt.

    pic20.jpg

    7. Urteil der positiven Frau

    Jetzt ist es endlich das lang erwartete Urteil der richtigen Frau! (Es dauerte ungefähr einen Tag, um hierher zu kommen)

    Wer war die positive Frau, die von AI beurteilt wurde? !! !!












    pic8.png

    ――Der Auserwählte war Ichihana </ b>.

    Nein, war es nicht die Länge der Haare? In Bezug auf die Farbe dachte ich, dass es auch im Mai einen Chan geben würde. Ich frage mich, ob es besser gewesen wäre, Sanku mit Kopfhörern zu kombinieren, die wie Audio Tenika aussehen.

    Nun, in der ersten Phase der Animation gab es fast keine Szenen, in denen andere Heldinnen als Ichihana ihre Haare erhoben, so dass es vernünftig sein kann, dass Ichihana ausgewählt wurde. Augen sind wichtiger als Haare als eine Eigenschaft, die das menschliche Gesicht bestimmt, aber im Fall von Quintuplets sind sie alle bläulich, so dass sie nicht zu unterscheiden waren. Infolgedessen habe ich das Gefühl, dass Ichihana wegen ihrer kurzen Haare ausgewählt wurde. Die Haarfarbe ist wie im Mai.

    Bonus

    Da es eine große Sache ist, habe ich versucht, auch andere Bilder zu klassifizieren.

    pic11.png Dies ist die Gelübdeszene aus der vorherigen Szene. Dies wurde auch als eine Blume klassifiziert. Immerhin sieht es aus wie eine Abkürzung.

    pic26.jpg

    Nun, das ist auch eine Blume ~~

    Und schließlich die letzte Szene von 8 Folgen. Dies ist ein Bild von einem Mädchen, in das sich Kazetaro vor langer Zeit verliebt hat.

    pic27.png

    e! Dies ist auch eine Blume! ?? ?? Ich denke, meine Haarfarbe war diesmal wie eine Blume, aber ich denke, Ichihana ist etwas zu stark ...

    Fazit

    In Bezug auf die KI sind die Heldin, die bei der Hochzeit als Braut herauskam, und das Mädchen, das es früher mochte, im Allgemeinen Ichihana-san </ b>. Das ist es. Etwas unangenehmes Heldinattribut einer älteren Schwester </ del> Eine Person, die Ichihana drängt, sagt: "Nein, sehen Sie, das liegt daran, dass Ichihana eine positive Frau in Bezug auf KI ist ..." Das könntest du sagen. Vielleicht.

    Referenz

    Ich habe versucht, die Animation "Keion!" Mit Keras zu erkennen Sammeln wir mit opencv Bilder von Anime-Charakteren aus Videos! Lbpcascade_animeface.xml zur Erkennung von Anime-Gesichtern durch OpenCV

    Recommended Posts