カメラで顔認識

・ここでは、べゼリーに内蔵したカメラで人間の顔を認識させてみます。

・顔の認識にはオープンソースの画像処理ライブラリ「Open CV(Open Source Computer Vision Library)」を使います。

準備

・まずはOpen CVをインストールしてください。

sudo apt-get install libopencv-dev python-opencv 
sudo apt-get install libatlas-base-dev

・「ラズパイカメラ」をクリアした状態(ラズパイカメラを接続し、HDMIディスプレイが接続された状態)にしておいてください。

サンプルプログラム sample_face1.py

・パソコンからの遠隔操作だと動画が表示されないことがあるので、ラズパイに直接つなげたキーボードとディスプレイで実行してください。(回避手段はありますが、ここでは説明しません)

$ python3 sample_face1.py

・ディスプレイに表示されているカメラ画像の中に顔(のようなもの)が収まると、赤い四角が表示され、ディスプレイに「顔を発見」と表示されるはずです。顔が画面からはみ出ていたり、傾いていたり、遠すぎると反応しません。
・終了したいときはキーボードの「q」ボタンを押してください。

ソースコード
#!/usr/bin/env python3
# -- coding: utf-8 --
# Bezelie Sample Code : Face Recognition Test
 import picamera                        # カメラ用モジュール
 import picamera.array                  # カメラ用モジュール
 import cv2                             # Open CVモジュール    
 import bezelie                         # べゼリー専用サーボ制御モジュール

 cascade_path =  "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml" # 顔認識xml
 cascade = cv2.CascadeClassifier(cascade_path)

# サーボの準備
 bez = bezelie.Control()               # べゼリー操作インスタンスの生成
 bez.moveCenter()                      # サーボをセンタリング
 
#メインループ
 def main():
   with picamera.PiCamera() as camera:                         # Open Pi-Camera as camera
     with picamera.array.PiRGBArray(camera) as stream:         # Open Video Stream from Pi-Camera as stream
       camera.resolution = (640, 480)                          # Display Resolution
       camera.hflip = True                                     # Vertical Flip 
       camera.vflip = True                                     # Horizontal Flip
       while True:
         camera.capture(stream, 'bgr', use_video_port=True)    # Capture the Video Stream
         gray = cv2.cvtColor(stream.array, cv2.COLOR_BGR2GRAY) # Convert BGR to Grayscale
         facerect = cascade.detectMultiScale(gray,             # Find face from gray
           scaleFactor=1.9,                                    # 1.1 - 1.9 :the bigger the quicker & less acurate 
           minNeighbors=3,                                     # 3 - 6 : the smaller the more easy to detect
           minSize=(80,120),                                  # Minimam face size 
           maxSize=(640,480))                                  # Maximam face size
         if len(facerect) > 0:
           for rect in facerect:
             cv2.rectangle(stream.array,                       # Draw a red rectangle at face place 
               tuple(rect[0:2]),                               # Upper Left
               tuple(rect[0:2]+rect[2:4]),                     # Lower Right
               (0,0,255), thickness=2)                         # Color and thickness
           print ("顔を発見")
         cv2.imshow('frame', stream.array)                     # Display the stream
         bez.movePitch (1, 0)
         if cv2.waitKey(1) & 0xFF == ord('q'):                 # Quit operation
           break
         stream.seek(0)                                        # Reset the stream
         stream.truncate()
       cv2.destroyAllWindows()
 
if name == "main":
   main()
解説

・9~10行目:顔認識のための分類器を読み込んでいます。
・24行目:カメラの画像をRGBでキャプチャーしています。
・25行目:RGB動画をグレースケールに変換しています。
・26~30行目:顔を認識しています。
・31~37行目:顔が見つかった場合の処理です。

応用

・27~30行目が顔を認識するためのパラメータです。いろいろ数値をいじってみましょう。例えばminSizeは顔として認識する最低のサイズですので、これを小さくすると、遠くの顔も認識されるようになります。そのかわり、壁に貼ってある写真など、顔じゃないものを誤認識する確率が上がってしまうかもしれません。