みなさんこんにちわ、こんばんわ
SAIです。
OpenCVをインストールできたので、
早速画像解析をしてみようと思います。
まずは、基本的な画像解析
顔認識に挑戦です。
OpenCVを勉強し始めたばかりなのに、
いきなり顔認識!?
と思いそうですが、
人物を認識するのではなく、
顔を認識するだけです。
以前、画像認識は特徴情報の学習が難しいと書いたと思いますが、
実は顔認識に使われる顔認識の特徴情報(カスケードというらしいです)が
公開されています。
以下、OpenCVのサイトから、
Windows用のOpenCV_x.xx.exeというファイルをダウンロードし
インストールしたところ、いろいろなカスケードが含まれていました。
OpenCV download | SourceForge.net
入っていた場所ですが、
OpenCVのインストールしたフォルダの下のこの辺にいっぱい入っていました。
./source/data/haarcascades
顔認識は、
haarcascade_frontalface_default.xml
これですね。
他にもeyeは目だったり、fullBodyは体だったりするので、
認識処理の勉強だけなら、ディープラーニングしなくてもできそうです。
簡単な人認識カメラくらいなら作れそうですね。
今回インストールしたOpenCV.exeですが、
どうやら、本来はC++などで実装する際に使う物みたいですね。
SAIはとりあえずカスケードが欲しいがためにインストールした感じです。(苦笑)
ある程度慣れてきたら、C++でも作ってみたいところですが、
SAIの手元にはVisualC++6.0という古物しかありません。
どうするかは、今後考えます。
話を戻して、PythonでOpenCVを使って顔認識をしたい!
それではpyのコードを書いてみたいと思います。
◆1 ライブラリの読み込み
ライブラリを読み込まなければなりません。
C言語でいうincludeが必要になります。
Pythonでは、
import cv2
これでよいみたいです。
◆2 カスケードを読み込み
画像認識するためには、特徴情報である、”カスケード”を読み込む必要があります。
pythonでは、
cv2を使って読み込みます。
cv2には、CascadeClassifier()という関数があり、
引数にカスケードのパスを入れてやることで、
カスケード情報が読み込めます。
具体的には、
pythonのコードを保存しているフォルダに、
顔認識用のカスケード
haarcascade_frontalface_default.xml
これを置いている前提で、
カスケードの読み込みは以下の記載でよいようです。
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
もし、別のフォルダだった場合はフルパス、又は相対パスを書けばよいみたいですね。
◆3 認識をしたい画像を読み込み
次は、画像認識をする画像の読み込みです。
以下、webからテキトーな画像を拝借しました。
集合写真の写真素材|写真素材なら「写真AC」無料(フリー)ダウンロードOK (photo-ac.com)
kao2.jpgとします。
この画像を、読み込みます。
画像の読み込みも、cv2の関数を使います。
cv2には、imread()という関数があり、
引数に読み込みたいイメージのパスを入れてやることで、
イメージ画像が読み込めます。
具体的には、
pythonのコードを保存しているフォルダに、
認識したい画像
kao2.jpg
これを置いている前提で、
画像の読み込みは以下の記載でよいようです。
img = cv2.imread('kao2.jpg')
◆4 認識をしたい画像のグレースケール化
どうやら、グレースケールの方が認識速度が速いため、
グレースケール化してから認識させているようです。
SAIは速度比較はしていませんが、サンプルがそのようにしろと言っているので、
とりあえずグレースケール化をすることにしました。
やり方は、やはりcv2の関数を使います。
cv2には、cvtColor()という関数があり、
引数に変換したい形式を指定すると、グレースケール化できるようです。
具体的には、
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
これだけですね。
いつか、グレースケール化をしない場合も試してみようかと思います。
というか、そもそも色を使わないとわからない認識をすることになれば、
必然的にグレースケールはしないことになるでしょうね。
◆5 カスケードによる画像解析
やっと今回の主役である解析処理です。
画像解析は、◆2で読みだしたカスケードを使い、
◆4で生成したグレースケール画像から顔の位置情報を取り出します。
使用する関数は、CascadeClassifier::detectMultiScale()
引数には、解析用の画像を入力します。
◆2で読みだした、
face_cascadeがCascadeClassifierですね。
具体的には、
faces = face_cascade.detectMultiScale(gray)
このような形です。
faces[] には、認識した位置情報が配列として格納されています。
◆6 認識した画像を加工する
認識した画像に対して、ここだよ!というマークを付けたいですよね。
ぼかしとかでもいいですが、認識が成功しているかどうかをはっきりさせるには、
枠で囲ってあげるのが良いのかなと思います。
画像認識しているサイトはみんなそうしているので、SAIもそうしてみます。
◆5では、認識した顔の位置情報を faces に入れましたので、
faces の数分だけループさせて、枠で囲います。
囲い方ですが、cv2には rectangle() という関数があります。
rectangleは、描画処理でよく使用する中抜き□(四角形)ですね。
イメージ画像に対し、四角の始点、四角の終点、色、線の太さ を指定する形で描画できます。
具体的には、
cv2.rectangle( img , (x,y) , (x+w,y+h) , (255,0,0) , 2)
画像 始点 終点 色(RGB) 太さdot
このような形です。
これを配列数だけ回せば、img に対して枠が引けますね。
◆7 加工した画像を保存する
ここまでで、img に対して認識した箇所に線を引きました。
これを保存、又は表示しないと認識が成功したかどうかの確認ができませんね。
表示も保存もcv2の関数で行えるようです。
OpenCVってすごいですね。
イメージを保存する場合ですが、imwrite()で行います。
手っ取り早く具体例です。
imgをkao2_detect.jpgとして保存する場合こんな感じです。
cv2.imwrite('kao2_detect.jpg', img)
また、イメージをプログラム上に表示する方法としては、 imgshow()です。
cv2.imshow('img',img)
ただしこちらは注意が必要です。
表示している間、プログラムを止めておく必要があるようです。
以下の呼び出しにてキーが押されるまで待機しておくようにするのがマナーのようですね。
cv2.waitKey(0)
そして、ウィンドウを表示しっぱなしだと邪魔くさいので、
プログラムが再開したら以下の関数で全部のウィンドウを閉じるのがマナーのようです。
cv2.destryAllWindows()
どうでしょうか?
顔認識に成功しました!
顔認識、
案外簡単ですね!
本日はここまでです。
それでは本日使用したコードを載せておきます。
import numpy as np
import cv2
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
img = cv2.imread('kao2.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray)
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imwrite('kao2_detect.jpg', img)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destryAllWindows()
うーん。
pythonの関数コメントやヘッダコメントって書きにくいね。
SAIにはpythonという言語が向いていない気がする。
おまけ。
SAIがブログを書いているときに見つけた↓のサイト
結構わかりやすく解説してくれそうだなって思ったり。
JetsonNanoのことを書いていたりするので、とりあえずメモ程度にリンクを残しておきたいと思います。
OpenCVのcascade.detectMultiScale関数で顔認証(Pythonサンプル)|産業用UVCカメラのすすめ|株式会社アルゴ (argocorp.com)