参考サイト・書籍
今回、参考にさせて頂いた主なサイト、書籍は下記の通りです。他にもいろいろなサイトを参考にさせて頂きましたが、自分の環境に最も近いと思われました。
【関連サイト】
Raspberry PiとOpenCVによる画像認識で人の顔を判別する
(パソコン工房社 チャレンジ&ナレッジ)
【参考書籍】
Pythonで始めるOpenCV3 (カットシステム社)
機械学習 カスケード分類器の準備
先回投稿でpython-opencvの設定は済ませているので、パソコン工房サイトでは、“機械学習データ(カスケード分類器)の準備”以降の項目を主に勉強させて頂きました。
パソコン工房サイトではラズパイ専用カメラを使用しているのに対して、私はUSBカメラを使っているので、“ Pythonで始めるOpenCV3”に記載プログラムの画像取り込みが、USB対応の様でしたので参考にしました。
予め OpenCVに用意されているカスケード分類器という人の顔の判定等に用いるデータ群を利用するので、先ず下記サイトからダウンロードします。
“GitHub – opencv/opencv: Open Source Computer Vision Library”
https://github.com/opencv/opencv/
「Clone or download」→「Download ZIP」をクリックしダウンロードします。
「opencv-master.zip」がダウンロードされたら、ダウンロードフォルダーに移動し、zip ファイルを解凍します。下図コマンド実行により opencv-master フォルダーが生成されます。
cd ダウンロード
unzip opencv-master.zip
下のパスのフォルダーを開くと、カスケード分類器ファイルを確認出来ます。各ファイルがそれぞれ異なる要素を判別する為に使用できる様です。
〈省略〉/ダウンロード/opencv-master/data/haarcascades
「 haarcascades」をフォルダー毎、python プログラムを保存しているフォルダーにコピーします。 「haarcascade_eye.xml」目と「haarcascade_frontalface_alt.xml」 顔を使います。
プログラム
プログラムは次の通りです。
import cv2 as cv try: capture = cv.VideoCapture(0) if capture.isOpened() is False: print("カメラを開けませんでした。") sys.exit() # https://github.com/opencv/opencv/tree/master/data/haarcascades cascade_face = cv.CascadeClassifier('haarcascades/haarcascade_frontalface_alt2.xml') cascade_eye = cv.CascadeClassifier('haarcascades/haarcascade_eye_tree_eyeglasses.xml') while True: ret, frame = capture.read() if ret == False: print('カメラからの映像を取得できませんでした。') continue # リサイズ frame = cv.resize(frame, (int(frame.shape[1]*0.7), int(frame.shape[0]*0.7))) # グレー変換 grayimg = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) # 顔検出 facerect = cascade_face.detectMultiScale( grayimg, scaleFactor=1.1, minNeighbors=2, minSize=(50, 50) ) if len(facerect) != 0: for rect in facerect: x = rect[0] y = rect[1] w = rect[2] h = rect[3] face_gray = grayimg[ y:y + h , x:x + w ] # 顔領域から目検出 eyesrect = cascade_eye.detectMultiScale( face_gray, scaleFactor=1.1, minNeighbors=3, minSize=(10, 10) ) # 目検出部分枠描画 if len(eyesrect) != 0: for rect_e in eyesrect: cv.rectangle( frame, (x + rect_e[0], y + rect_e[1]), (x + rect_e[0] + rect_e[2], y + rect_e[1] + rect_e[3]), (0, 255, 255), thickness=2 ) # 顔検出部分枠描画 cv.rectangle( frame, (x, y),(x + w, y + h), (255, 255, 255), thickness=2 ) cv.imshow('frame', frame) # キー入力を1ms待って、k が27(ESC)だったらBreakする k = cv.waitKey(1) if k == 27: break # キャプチャをリリースして、ウィンドウをすべて閉じる cap.release() cv2.destroyAllWindows() except: import sys print("Error:",sys.exc_info()[0]) print(sys.exc_info()[1]) import traceback print(traceback.format_tb(sys.exc_info()[2]))
結果
下の写真はフリー画像を別のパソコンのモニターに表示し、ラズパイに接続しているUSBカメラで連続的に撮像・顔認識したときのウィンドウをキャプチャーしたものです。自分自身の撮像・顔認識もしましたが、認識できました。
顔認識は傾きやカメラとの距離等によって、認識されないことも多々ありますが、比較的良好と思います。目認識は下図でも判る様に現設定では認識率は良いとは言えません。
それでも顔認識が、この様な簡単な設定と少しのプログラム変更で実現できることには驚かされます。
まとめ
計測器等のデジタル数字の読み取りを行いたいのですが、適したカスケード分類器は無いようでした。ロシアのナンバープレート用みたいのはありましたが、使えるのでしょうか? カスケード分類器 も自作できる様ですので、いろいろ検討してみます。