私的AI研究会 > OpenCV4
OpenCV に実装されているカスケード分類器を使った処理を検証をしてみる。
OpenVINO™ ツールキットをインストールした環境で検証する。
pi@raspberrypi:~ $ python3 Python 3.7.3 (default, Jul 25 2020, 13:03:44) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> cv2.__version__ '4.5.1-openvino' >>> quit()
~/work-opencv
$ cd ~/Downloads $ unzip opencv-master.zip
$ cd opencv-master/data $ cp -r haarcascades ~/work-opencv $ ls ~/work-opencv/haarcascades haarcascade_eye.xml haarcascade_frontalface_alt_tree.xml haarcascade_profileface.xml haarcascade_eye_tree_eyeglasses.xml haarcascade_frontalface_default.xml haarcascade_righteye_2splits.xml haarcascade_frontalcatface.xml haarcascade_fullbody.xml haarcascade_russian_plate_number.xml haarcascade_frontalcatface_extended.xml haarcascade_lefteye_2splits.xml haarcascade_smile.xml haarcascade_frontalface_alt.xml haarcascade_licence_plate_rus_16stages.xml haarcascade_upperbody.xml haarcascade_frontalface_alt2.xml haarcascade_lowerbody.xml
ファイル名 | 対象物 |
haarcascade_eye.xml | 目 |
haarcascade_eye_tree_eyeglasses.xml | 眼鏡 |
haarcascade_frontalcatface.xml | 猫の顔(正面) |
haarcascade_frontalcatface_extended.xml | 猫の顔(正面) |
haarcascade_frontalface_alt.xml | 顔(正面) |
haarcascade_frontalface_alt2.xml | 顔(正面) |
haarcascade_frontalface_alt_tree.xml | 顔(正面) |
haarcascade_frontalface_default.xml | 顔(正面) |
haarcascade_fullbody.xml | 全身 |
haarcascade_lefteye_2splits.xml | 左目 |
haarcascade_licence_plate_rus_16stages.xml | ロシアのナンバープレート(全体) |
haarcascade_lowerbody.xml | 下半身 |
haarcascade_profileface.xml | 顔(証明写真) |
haarcascade_righteye_2splits.xml | 右目 |
haarcascade_russian_plate_number.xml | ロシアのナンバープレート(数字) |
haarcascade_smile.xml | 笑顔 |
haarcascade_upperbody.xml | 上半身 |
~/work-opencv $ vi face_eye.py # -*- coding: utf-8 -*- """ カスケード分類器 顔と目を探す """ import cv2 import time def __main(): img = cv2.imread('face9.jpg') img = getResize(img) timeStart = time.time() # ここから処理を実行する img = getProcess(img) timeEnd = time.time() print("{0} = {1}".format('CPU', (timeEnd - timeStart) * 1000) + "/ms") cv2.imshow('Final result', img) cv2.waitKey(0) cv2.destroyAllWindows() def getProcess(img): global face_cascade, eye_cascade # 顔検出の処理効率化のために、写真の情報量を落とす(モノクロにする) grayimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 顔検出を行う facerect = face_cascade.detectMultiScale(grayimg, scaleFactor=1.2, minNeighbors=2, minSize=(1, 1)) # 目検出を行う eyerect = eye_cascade.detectMultiScale(grayimg) print(facerect) print(eyerect) # 顔を検出した場合 if len(facerect) > 0: # 検出した場所すべてに赤色で枠を描画する for rect in facerect: cv2.rectangle(img, tuple(rect[0:2]), tuple(rect[0:2]+rect[2:4]), (0, 0, 255), thickness=3) # 目を検出した場合 if len(eyerect) > 0: # 検出した場所すべてに緑色で枠を描画する for rect in eyerect: cv2.rectangle(img, tuple(rect[0:2]), tuple(rect[0:2]+rect[2:4]), (0, 255, 0), thickness=3) return img def getResize(img): basePixSize = 1280 # 縦横で大きい辺の変更したいサイズ height = img.shape[0] width = img.shape[1] largeSize = max(height, width) # 大きい方の辺のサイズ resizeRate = basePixSize / largeSize # 変更比率を計算 img = cv2.resize(img, (int(width * resizeRate), int(height * resizeRate))) return img if __name__ == '__main__': print(cv2.__version__) # 顔検出のための学習元データを読み込む face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml') # 目検出のための学習元データを読み込む eye_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_eye.xml') __main()
~/work-opencv $ python3 face_eye.py 4.5.1-openvino [[778 189 156 156] [505 266 168 168] [404 389 55 55]] [[402 163 23 23] [593 177 24 24] [ 20 69 86 86] [859 224 45 45] [798 229 46 46] [535 307 46 46] [595 313 39 39] [824 286 47 47] [557 366 49 49]] CPU = 1057.8985214233398/ms
~/work-opencv $ vi cam_face.py # -*- coding: utf-8 -*- """ カスケード分類器 顔を認識したら写真を撮影する """ import cv2 import numpy as np def __main(): # カメラ準備 cap = cv2.VideoCapture(0) # メインループ while True: ret, frame = cap.read() img = getResize(frame) # Reload on error if ret == False: continue # 顔検出の処理効率化のために、写真の情報量を落とす(モノクロにする) grayimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 顔検出を行う facerect = face_cascade.detectMultiScale(grayimg, scaleFactor=1.2, minNeighbors=2, minSize=(100, 100)) # 顔が検出された場合 if len(facerect) > 0: # そのときの画像を保存する cv2.imwrite('my_face.jpg', frame) break # 画像表示 cv2.imshow('Object-Detect', frame) # 何らかのキーが押されたら終了 key = cv2.waitKey(1) if key != -1: break # 画像表示 cv2.imshow('Object-Detect', frame) # キーが押されたら終了 cv2.waitKey(0) # 終了処理 cap.release() cv2.destroyAllWindows() def getResize(img): basePixSize = 1280 # 縦横で大きい辺の変更したいサイズ height = img.shape[0] width = img.shape[1] largeSize = max(height, width) # 大きい方の辺のサイズ resizeRate = basePixSize / largeSize # 変更比率を計算 img = cv2.resize(img, (int(width * resizeRate), int(height * resizeRate))) return img if __name__ == '__main__': print(cv2.__version__) # 顔検出のための学習元データを読み込む face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml') __main()
~/work-opencv $ vi cam_face1.py # -*- coding: utf-8 -*- """ カスケード分類器 動画の中で顔を捕捉、追従する """ import cv2 import time def __main(): # カメラ準備 cap = cv2.VideoCapture(0) # メインループ while True: ret, frame = cap.read() img = getResize(frame) # Reload on error if ret == False: continue # 顔検出の処理効率化のために、写真の情報量を落とす(モノクロにする) grayimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 顔検出を行う facerect = face_cascade.detectMultiScale(grayimg, scaleFactor=1.2, minNeighbors=2, minSize=(10, 10)) # 顔が検出された場合 if len(facerect) > 0: # 検出した場所すべてに赤色で枠を描画する for rect in facerect: cv2.rectangle(img, tuple(rect[0:2]), tuple(rect[0:2]+rect[2:4]), (0, 0, 255), thickness=3) # 画像表示 cv2.imshow('Object-Detect', img) # 何らかのキーが押されたら終了 key = cv2.waitKey(1) if key != -1: break # 終了処理 cap.release() cv2.destroyAllWindows() def getResize(img): basePixSize = 640 # 縦横で大きい辺の変更したいサイズ height = img.shape[0] width = img.shape[1] largeSize = max(height, width) # 大きい方の辺のサイズ resizeRate = basePixSize / largeSize # 変更比率を計算 img = cv2.resize(img, (int(width * resizeRate), int(height * resizeRate))) return img if __name__ == '__main__': print(cv2.__version__) # 顔検出のための学習元データを読み込む face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml') __main()
facerect = face_cascade.detectMultiScale(grayimg, scaleFactor=1.2, minNeighbors=2, minSize=(10, 10))