人物の画像を入力するとアニメか写真か自動で判断するプログラム【python】

#　はじめに
機械学習でいろいろする為に顔認識の勉強をしていたのですが息抜きに作ったものです。
人物の画像を入れるとそれがアニメか写真かを判断してくれます。
顔を基準にしている為リアルな絵を入れると写真だと判断することがあります。
実写風のリアルな絵を通してpcによってそれが本当に現実に近いかどうか判別するのに使えるのではないでしょうか。

# 用意する物
python3.○
pythonのバージョンに対応したOpenCV
写真用アニメ用のカスケード分類器（後述）

# 開発
単純な物なので必要な物が手に入ったら早速コーディングしていきましょう。

##　実装

```ディレクトリ
（フォルダ）img-画像置き場
（フォルダ）haarcascade-カスケード分類器置き場
（ファイル）auto_anime_classifier.py
```
以上の物を同一ディレクトリ内に配置してください
今回haarcascadeフォルダに置くファイルは
 - haarcascade_frontalface_alt.xml
 - lbpcascade_animeface.xml
この二つです。前者はOpenCVにデフォルトで入っています。後者はhttps://github.com/nagadomi/lbpcascade_animeface

ソースコード

```auto_anime_classifier.py
import cv2
import numpy as np

if __name__ == '__main__':

    CASCADE_PATH = 'haarcascade/'
    face_count = []

    print('Plz input filename')
    img_name = input('>> ')
    img = cv2.imread('img/'+str(img_name), cv2.IMREAD_COLOR)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    photo = cv2.CascadeClassifier(CASCADE_PATH + 'haarcascade_frontalface_alt.xml')
    anime = cv2.CascadeClassifier(CASCADE_PATH + 'lbpcascade_animeface.xml')

    face_count.append(len(photo.detectMultiScale(gray, 1.1, 3)))
    face_count.append(len(anime.detectMultiScale(gray, 1.1, 3)))

    if face_count[0] > face_count[1]:
        print('Maybe photo.')
    elif face_count[1] > face_count[0]:
        print('Maybe anime.')
        elif face_count[0] >= 1 and face_count[1] >= 1:
        print('Both attributes.')
    elif face_count[0] == 0 and face_count[1] == 0:
        print('Undeciable.')
```

##　解説
OpenCVについては素晴らしい内容の解説ブログ等が山ほどある為ほとんど省略します。
imgフォルダ内の画像を入力、それをimread()で読み込み。その後グレー加工をします。

```
print('Plz input fiｌename')
img_name = input('>> ')
img = cv2.imread('img/'+str(img_name), cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
```

写真、アニメそれぞれのカスケード分類ファイルを読み込んだ分類器を作成。

```
photo = cv2.CascadeClassifier(CASCADE_PATH + 'haarcascade_frontalface_alt.xml')
anime = cv2.CascadeClassifier(CASCADE_PATH + 'lbpcascade_animeface.xml')
```

face_count内にそれぞれの分類器で読み取れた数を格納。これの有無が判断基準となります。

```
face_count.append(len(photo.detectMultiScale(gray, 1.1, 3)))
face_count.append(len(anime.detectMultiScale(gray, 1.1, 3)))
```

最後に判断部分です。シンプルに認識できているかそうでないかで比較します。

```
if face_count[0] > face_count[1]:
   print('Maybe photo.')
elif face_count[1] > face_count[0]:
   print('Maybe anime.')
elif face_count[0] >= 1 and face_count[1] >= 1:
   print('Both attributes.')
elif face_count[0] == 0 and face_count[1] == 0:
   print('Undeciable.')
```

現実の近さ
Maybe photo（多分実写だよ） → Both attributes（どっちでも通用するよ） → Maybe anime（多分絵だよ） → Undeciable（わからん。問題外）

# 遊ぶ
説明は程々にして遊びましょう。

##普通に使う
![beatles.jpeg](https://qiita-image-store.s3.amazonaws.com/0/160607/ef6947be-9704-f6cb-563c-c1a2c5509acd.jpeg)
ビートルズです。かっこいいですね〜

```
Plz input filename
>> beatles.jpeg
Maybe photo.
```

写真らしいです。そらそうだわ。


![aoba.jpeg](https://qiita-image-store.s3.amazonaws.com/0/160607/290d57ad-35b0-66b1-a0b4-bca9815c4172.jpeg)
NEWGAMEの主人公です。かわいいですね〜

```
Plz input filename
>> aoba.jpeg
Maybe anime.
```

アニメだそう。まあ見りゃわかりますね。

##微妙な画像を入れて遊ぶ
普通にやっても何も面白くなかったのでプログラムがどっちを示すかわからない映像を入れてみましょう。

![seeu.png](https://qiita-image-store.s3.amazonaws.com/0/160607/45430a7b-058d-27da-d493-27d76e9521f0.png)
中国のレイヤーSeeUさんという方です。画像は本人のTwitterからの引用です。

```
Plz input filename
>> seeu.png
Maybe anime.
```

アニメらしい。人間から見るとあまり絵の感じはないですね。
画像加工がものをいうのでしょうか。

![kuroisabaku.png](https://qiita-image-store.s3.amazonaws.com/0/160607/5adc283a-fb8d-30dd-fa4e-a8d9103b6ff5.png)
黒い砂漠というMMORPGで作成されたキャラクターです。キャラクリに何時間もかけてしまうタイプのゲーム。
*引用元(ttp://sumimarudan.blog7.fc2.com/blog-entry-2245.html)*

```
Plz input filename
>> kuroisabaku.png
Both attributes.
```

どっちでもいけるらしい。黒目が大きいことと鼻が小さいことを除けばあまり絵の感じはしないような気がするんですけどね〜

![honey.jpeg](https://qiita-image-store.s3.amazonaws.com/0/160607/6578b983-5734-f6b0-20b2-a55082b6b57c.jpeg)
ハニーセレクトというゲームで作られた男性キャラクターです。illusionのキャラクリは若者以外のキャラクターも違和感なく作れますね。

```
Plz input filename
>> honey.png
Maybe photo.
```
写真らしい。やっぱ鼻の形が重要な分岐点なのかな。
ちなみにPSO2で作った男性キャラクターは絵の扱いでした。

![orient.jpg](https://qiita-image-store.s3.amazonaws.com/0/160607/7d968378-17d9-216c-d7ae-cbbdc004dda9.jpeg)
オリエント工業の人形さん。とても現実っぽい。

```
Plz input filename
>> orient.jpg
Both attributes.
```
なんとアニメ要素ありでした。なんでだろうか…

#終わりに
今回のプログラムはただそれぞれの判断器が顔を認識できるかどうかの物でした。改良するとすれば各判断器から細かい判断要素について出力させ数値としてパラメータをつくってやる必要があると感じました。カスケード分類について勉強しなくてはならない。
長くなってしまいましたが、ここまでご覧いただきありがとうございました！！