TwitterのTLから二次元画像だけ収集しよう! (6)精度をTPTSと同じにする

さて、このシリーズも本編に関してはこれで終わりです。
正直、前回までで機能は全部実装してしまったので今回もおまけみたいなものに見えますけど…

今回は前回まで使用していたlbpcascade_animefaceではなく、僕が学習させたモデルを使用してみます。

では、いつものスクリプト配布です。

GitHub Gist – TL_capture_dlib.py
detector_face.svm – marron-akanishi/TPTS_web(直リン、右クリックで保存を推奨)
detector_eye.svm – marron-akanishi/TPTS_web(直リン、右クリックで保存を推奨)

Gistの中には2つファイルがあります。
毎回のことですが、dlib_detector.pyのファイル名は変えないでください。参照できなくなります。
今回はモデルが変わるので、そのモデルも配布しています。2つありますが、どちらもダウンロードしてください。

では、実行してみます。最後ですし、もう説明要らないよね?

実行結果も何も変わりません。
ファイル数が増えたので、少し整理した状態のフォルダー構造にしてあります。

 

では、メインスクリプトの変更点です。

クリックで拡大できます。左が前回、右が今回のスクリプトとなっています。

なんと変更点が1つしかありません。
検出部分を変えただけなので、こっちの変更がほとんど無いのです。

変更した部分はimport文だけです(10行目)。ここも関数名はそのままでファイル名を変えただけとなっています。

ということで肝心の検出用スクリプトをさっそく見ていきます。

import numpy as np
import cv2
from dlib import simple_object_detector

face_detector = simple_object_detector("./detector_face.svm")
eye_detector = simple_object_detector("./detector_eye.svm")

def face2d_detect(raw_file):
    # 取得するか
    is_get = False
    # 顔の位置
    facex = []
    facey = []
    facew = []
    faceh = []

    # 画像をデコード
    image = cv2.imdecode(np.asarray(bytearray(raw_file), dtype=np.uint8), 1)
    # 画像から顔を検出
    try:
        faces = face_detector(image)
    except:
        faces = 0
    # 顔が検出出来たか
    if len(faces) > 0:
        # 顔だけ切り出して目の検索
        for i, area in enumerate(faces):
            face = image[area.top():area.bottom(), area.left():area.right()]
            # 出来た画像から目を検出
            eyes = eye_detector(face)
            if len(eyes) > 0:
                facex.append(area.left())
                facey.append(area.top())
                facew.append(area.right()-area.left())
                faceh.append(area.bottom()-area.top())
                is_get = True
    return is_get, [facex, facey, facew, faceh]

いつものようにコードを埋め込んでみました。では、見ていきます。
ちなみにlbpcascade.pyと変更がない部分は飛ばしていきます。
説明内での行番号はファイル内での行番号となっているので、上のスクリプトで見る際は-2した行番号でみてください。

まず、今回はdlibと呼ばれるライブラリを利用して検出を行うため、import文が増えています(5行目)。

次にモデルのロードです(7~8行目)。
前回までは1つしかファイルが無かったので、1行で済んでいましたが今回は2つ使用するため、2つ検出器を作成しています。なぜ2つあるのかは後から説明します。

次に取得するかのフラグを別の変数として用意しました(12行目)。
前回までreturnに直書きしていたフラグを変数に分けただけです。

次に画像の読み込みが少し変化しています(20行目)。
今まではグレースケールに変換していましたが、今回は変換していません。変化が特に見られなかったので、変換するのを止めただけです。別に前回同様にグレースケールに変換しても問題ありません。

次に顔検出を行います(22~25行目)。
ここでエラー処理を行っています。これはたまに画像の形式が対応していなくてエラーを吐くことがあったため、実装しました。face_detectorの返却値は前と同様に座標情報群です。

次に顔が検出できたかを確認しています(27行目)。これも前回までと変わりません。

次に画像から顔だけを切り出して、目を検出しています(29~32行目)。ここが前回までと大きく異なる場所です。
前回までは顔が検出できたら、そのまま座標情報をリストに突っ込んでいました。
ですが、その結果顔では無いところまでリストに入ってしまいました。
そこで今回は顔として検出できたなら目も存在するだろうということで、目の検出を行っています。これにより、精度が改善されました。ただ、逆に言えば判定が厳しくなったので取りこぼす確率も上がりました。どちらがいいかはまあ人それぞれって感じですかね。
ちなみに顔のみで行うと精度が結構下がります。学習が悪かっただけなのですが…

目が検出できたら、そのデータをリストに登録してフラグをTrueにします(33~38行目)。
前回まではただのリストだったので座標を数字で指定していましたが、今回はメソッドで取得しています。こっちのほうが読みやすいですね。

最後にフラグとリストを返却しています(39行目)。特に変更はありません。

顔検出部分の変更点はこんな感じです。

 

では、理論的な部分の説明にいきましょう。いつものように参考URLをいくつか貼っていきます。

前回まではOpenCVに入っている検出器を使用していましたが、今回は機械学習用ライブラリであるDlibの検出器を利用してみました。特にDlibじゃないといけないというこだわりは無いのですが、検索していると見つかったので使ってみたという感じです。

dlibを用いた顔検出器と物体検出器とその学習 – Stimulator
– はじめに – dlibのSimple_Object_Detectorクラスを使った物体検出用カスケードの学習をする記事。dlibは機械学習ライブラリとして2006年から始まったプロジェクトで、基本的なSVMや線形アルゴリズム、Bayesian Network等に加えて、機械学習関係で用いるような画像処理ツールやグラフツールが付属している。dlib C++ Libraryこの素敵な図を見たことある人も居ると思う dlibは画像からの物体検出として顔検出を代表としたオブジェクト検出用のクラスが用意されている。 中身はHoG+SVMとシンプルな構成だが、矩形情報と正例画像を与えるだけで、学習用サ…
dlibのSimple_Object_detectorを用いたPythonでの物体検出器の学習 – Stimulator
– はじめに – これはこの記事の続きで、dlibを使って物体検出をしようというものである。まあ正確には、dlibには「顔検出器の学習」ってのは無くて「物体検出器の学習」の機能を使って、顔検出器の再学習がしたいという記事です。dlibを使う際の参考になればよいです。 – dlibのObjectDetectorについて – dlibに物体検出の学習が入ったのは2014年の時。 内部にはHoG+SVMを使っていて、OpenCVで学習する場合に比べて、遥かに少ない学習データで、かなりの精度を出す事ができる。リリース時の本家記事 : dlib C++ Library: Dlib 18.6 releas…

一番最初に見つけたサイトです。特に学習部分はお世話になりました。

dlibによるHOG特徴を用いた物体検出がすごい – kivantium活動日記
dlibを用いたselective searchで紹介したSegmentation as Selective Search for Object Recognitionを読んだところ、selective searchした候補領域に対してHOG特徴量を取ってSVMで物体かどうかの判定を行っていたのでHOG+SVMによる物体検出器を使ってみます。ここではdlibの実装を使います。 dlibのPythonラッパーのインストールはdlibを用いたselective searchを参照してください。 教師データの作成 ラベリング用プログラムはOpenCVでの物体検出器作成にあるものを使います。出力をこの…

こっちも読みました。

今回のモデルはHOG特徴とSVM(サポートベクターマシン)というものを使用しています。

HOG特徴量とSVMを使った自動車の検出 – くーろんログ
あけましておめでとうございます。去年の10月に研究室に配属されてからあれよあれよという間に年を越してしまいました。課題研究の関係で論文を色々漁ったのと去年の夏のインターンシップで一般物体認識をやったのでここらで一旦まとめる為にエントリを残しておきます。本エントリは初心者の方が対象であるのと、私自身まだ機械学習を始めてから日が浅いので間違いや危ない表現も多いかと思います。今回は自動車の検出をやろうと思います。巷ではDeepLearningが流行ってますがそんなことは気にせず、少し古い手法ですがHOG+SVMでやっていきます。 HOG特徴量 (Histograms of Oriented Grad…

どっちも載ってるありがたいページを見つけました。説明は全部丸投げします(おい

読めば分かりますが、実は検出は前回と同様にグレースケールで行われています。なら、グレースケールにしたほうが速いのでは…

ちょっとここで検出結果を見てみましょう。形式は前から変更していないので、今回のDBもTPTSViewerで開くことができます。

さて、少し精度が下がっていますね。ですが、まあ画像としては収集できているので今回はよしとしましょう。

で、枠のサイズを見ていただきたいのですが顔ギリギリを取ってます。
これは僕が学習させたときにギリギリで囲っていったからです。こっちのほうがいいと思いませんか?

 

今回はこれぐらいで終わります。本当は学習まで書こうと思ったのですが、別の記事に分けることにしました。なんかね、今日疲れてるんですよ。
学習に関しては、少し環境の整備が必要なんですよね。特に今回配っているPythonが32bit版なのですが、学習には64bit版が必要になります。メモリをそれだけ使用するってことです。

機械学習というとどうしても最近だとディープラーニングばかりが注目されていますが、こんな感じの昔ながらの方法でも結構面白いことが出来ます。
ただ、ディープラーニングを利用したほうがもっと出来ることが増えるのは確かです。

ちなみに今回学習させたデータは僕はTPTSを作ってすぐに作成したものです。
それ以降もたまに作っていたのですが、これ以上精度が良いものが出来ないというのが現状です。というのも、これ以上データを増やして学習すると逆に過学習に陥って、精度が下がるんですよね。やっぱり方式変えるしか無いようです。
ただ、僕GPUがRX460なんで学習に使えないんですよね。誰かGTX 1060をください。

今回は二次元画像の収集という名目でやりましたが、これをするなら一番ベストなのは写真とイラストを判別することだとずっと思っています。
ただ、いい方法が思いつきません。いいアイデアが欲しいですね。

さて、これで皆さんもTPTSを作ることが出来ました(単にスクリプトを配布していただけ?)。
バックがこれで出来ているTPTS_webでは、TL以外の場所からも画像を収集出来るので使ってみてください。Twitterアカウントでログインするだけで使用できます。

次回は番外編の予定ですが、いつになるか分かりません。
それではお疲れ様でした。

投稿者: 赤西 真論

アイマスに人生を変えられ、コードを書くのが嫌いになった大学生

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください