読者です 読者をやめる 読者になる 読者になる

【DeepLearning】物語シリーズのキャラを認識して分類する

さて例のごとくkivantiumさんのページを辿って画像の収集に乗り出します。*1

 

ニコニコ動画のダウンロードツール nicovideo-dlは

公式で使用不可になったのか

ログイン時にエラーとなりましたので

今回はyoutubeの公式PVの動画から化物語サンプルを取り出しました。

(最初に野良動画を使おうとして途中でやり直したのはここだけの秘密だ)

 

kivantiumさんのページにある

下記の顔まわりの画像を生成するコードを実行します。

実行方法とか詳しくはkivantiumさんのページをちゃんと読みましょう

 

Ubuntu 14.04の環境で実施

youtube動画のダウンロード*2

$ sudo apt-get install youtube-dl

$ youtube-dl www.youtube.com/watch?v=gVOVIF8GYmo

 

>|cpp|

#include <opencv2/opencv.hpp> #include <string> #include <sstream> #include <iomanip> using namespace std; using namespace cv; void detectAndDisplay(Mat image); CascadeClassifier face_cascade; int imagenum = 0; int main(int argc, char* argv[]){ int framenum = 0; //カスケードのロード face_cascade.load("lbpcascade_animeface.xml"); //動画の読み込み Mat frame; VideoCapture video("video"); if(!video.isOpened()){ cout << "Video not found!" << endl; return -1; } for(;;){ framenum++; video >> frame; if (frame.empty()) { cout << "End of video" << endl; break; }; //全フレーム切りだすと画像数が増え過ぎるので10フレームごとに検出 if(framenum%10==0) detectAndDisplay(frame); } return 0; } //認識と表示を行う関数 void detectAndDisplay(Mat image) { vector<Rect> faces; Mat frame_gray; stringstream name; //画像のグレースケール化 cvtColor(image, frame_gray, COLOR_BGR2GRAY ); //ヒストグラムの平坦化 equalizeHist(frame_gray, frame_gray); //顔の認識 小さい顔は除外 face_cascade.detectMultiScale(frame_gray, faces, 1.1, 3, 0, Size(80,80)); for(int i = 0; i<faces.size(); i++){ //顔部分に注目したMatをROIで作る Mat Face = image(Rect(faces[i].x, faces[i].y,faces[i].width, faces[i].height)); //連番のファイル名を作る。参考:http://www.geocities.jp/eneces_jupiter_jp/cpp1/013-001.html name.str(""); name << "image" << setw(3) << setfill('0') << imagenum << ".png"; imwrite(name.str(), Face); imagenum++; } }

||<

コンパイル

g++ Anime.cpp -o anime `pkg-config opencv --cflags --libs`

 

公式PVを使用したところ、下記の9名のクラスに分類出来ました。

train配下に9人の名前で分類しています。

 DIGITSはTrain用のデータセットから抜き出して検証用のDBを作るらしく汎化性能を確認する為にvalディレクトリには上記とは別のPV動画から抽出した画像を保存します。

data --train --shinobu

                   --koyomi

                   --hitagi

                   --kanbaru

                   --hachikuji

                   --nadeko

                   --karen

                   --tsukihi

                   --numachi

         --val  --なんか適当な画像(検証用dbには関係ない)

 ▼生成された画像 これをディレクトリ分けする

f:id:manjirou99:20160416004416p:plain

 

 

DIGITSでデータセット作成時に上記のdataディレクトリを指定し、

データセットを作成します。

こんな感じでラベリングされた顔画像データを格納したDBが出来ました。

f:id:manjirou99:20160416015434p:plain

このデータセットを使ってGoogeLeNetで学習させます。

きゅいーん

f:id:manjirou99:20160416010908p:plain

 

学習が完了したモデルにvalから適当に画像を選んで判定させてみます。

忍の画像判定結果

f:id:manjirou99:20160416011709p:plain

暦の画像判定結果

 

f:id:manjirou99:20160416011212p:plain

 

八九寺の判定結果

f:id:manjirou99:20160416011613p:plain

 

忍が100%なのは一人だけ僕の個人的な理由により

学習用画像枚数が多かったからですね

忍の学習用画像は166枚でした

学習用枚数が12枚だった八九寺はひたぎと誤認されてしまっています。

とりあえずは各100枚以上画像があればアニメキャラの分類器はいけるかも?

 

次はキャラの数を増やして学習画像数を調整してみましょう 

 

続く

 

*こういうふうに改良したほうがいい

 どこか改善点がある

 こうした方が面白くなるよ!とか

 ご意見いただけたら嬉しいです

 

参考にさせて頂いたkivantiumさん、

アニメ顔のカスケード分類用ファイルを公開頂いたultraistさんに改めて感謝申し上げます。

参考ページ:

  1. ご注文は機械学習ですか? - kivantium活動日記
  2. OpenCVによるアニメ顔検出ならlbpcascade_animeface.xml - デー

公式PVをyoutubeで公開して頂いている

シャフトさん、Aniplexさんにも御礼申し上げます。

画像採取に使わせてもらった公式動画

  1. 物語シリーズ CM集 6Ver【TV spot】Monogatari Series - YouTube
  2. 物語シリーズ セカンドシーズンのPV第1弾 - YouTube

*1:参考ページ1.

*2:公式動画1