動機
「Opencvちゃん,macの内臓カメラで顔検出ができるのは分かったから好きなもんを認識させてくれや...」ということでcascade分類器を自作しようとしたら思ったより時間食ったのでいろんなサイトを参考にしてうまくいったところで備忘録作っておこうと思って書きました.
※所要時間30分程度
開発環境
・macOS High Sierra バージョン 10.13.6
・Python 3.6.4
・anaconda3 仮想環境 (Navigator使いました)
・opencv-python
今回は訳あってこちらのパッチを認識していきたいと思います.
Adversarial Patch
https://www.youtube.com/watch?v=i1sp4X57TL4
さっそくやってみる
OpenCVをbrewで入れる
お使いのmacにHome brewが入れてある前提でやっていきます.
$brew install opencv
$opencv_traincascade
と打って
Usage: opencv_traincascade
と出てくればきちんとopencvがインストールされていると思われる(※後で使います)
ディレクトリを作成する
任意のディレクトリに以下のように各フォルダを作ってください.
ーpos(正解画像を保存するフォルダ)
ーvec(正解画像ベクトルファイル用フォルダ)
ーneg(不正解画像を保存するフォルダ)
ーcascade/trained_data (分類器用フォルダ)
画像配置
pos/の中に、上の画像をpatch.jpgと名前をつけて保存して,正解画像(以下、ポジティブ画像)として入れる.
pos/patch.jpg
neg/の中に、不正解画像(ネガティブ画像)を入れる
neg/100000.jpg
neg/100001.jpg
.....
ネガティブ画像は、patch以外ならどんな画像でもいいらしいのですが,結構量がないといけなかったのでINRIAdatasetから持ってきました.(jpg1.tar.gzってやつ)
http://lear.inrialpes.fr/~jegou/data.php#holidays
Tar.gzの解凍コマンドで解凍したら
https://qiita.com/takatyu/items/4cff84a6935556204b2a
上図のようにnegの下に配置してください.
ベクトルデータを作る
一枚の画像からベクトルデータを作成します。
opencv_traincascadeコマンドを使うと、一枚の画像を変形させて 数千枚以上のベクトルデータを作成することができる。
$opencv_createsamples -img ./pos/patch.jpg -vec ./vec/patch.vec -num 100 -bgcolor 255 -w 44 -h 44
ネガティブ画像のリストを1つのファイルにまとめる
$ls neg | xargs -I {} echo neg/{} > nglist.txt
実際に分類器を作成する
$opencv_traincascade -data ./cascade/trained_data/ -vec ./vec/patch.vec -bg nglist.txt -numPos 100 -numNeg 100 -w 44 -h 44
そうするとcascade.xmlが作成される,それがcascade分類器になる.
macのカメラで写してみる.
上記のサイトのコードを
ーpos(正解画像を保存するフォルダ)
ーvec(正解画像ベクトルファイル用フォルダ)
ーneg(不正解画像を保存するフォルダ)
ーcascade/trained_data (分類器用フォルダ)
ーcapture.py
のように配置して保存する.
その後.
# OpenCVに用意されている顔認識するためのxmlファイルのパス
cascade_path = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"
を
# OpenCVに用意されている顔認識するためのxmlファイルのパス
cascade_path = "./cascade/trained_data/cascade.xml"
と書き換えて
$python capture.py
で実行するとmacの内臓カメラでこんな感じにリアルタイムで検出できる.(レイテンシのせいで少しずれちゃっていますが)

あとは自分の認識させたい画像をpos/に入れて学習させてみてください.
学習枚数が100枚ずつだけなのであまり精度はでませんでしたが,もう少しデータを増やしてやってみたいと思います.
試してみたところopencv_createsamplesで作成できるのは100枚が限界でした.
P.S.
機械学習,自動運転などをメインに(たまにそれ以外も)発信しているのでぜひこのQiitaと twitterのフォローおねがいします.
参考サイト
ピカチュウ先輩の認識
http://workout-engineer.com/python-opencv-cascade/
物体検出 – HaarLike 分類器の作成 for mac
http://copycat.tokyo/copy-from/543/
http://copycat.tokyo/copy-from/577/