顔認証サンプルスケッチ Face detectionの仕組みをまとめてみる
サンプルスケッチ
どこに書いてあるかわかりやすくするため
まずは全文表示する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
/* Face detection example with OpenCV */ /* Public Domain */ #include <Arduino.h> #include <Camera.h> #include <opencv.hpp> #include <DisplayApp.h> // To monitor realtime on PC, you need DisplayApp on following site. // Connect USB0(not for mbed interface) to your PC // https://os.mbed.com/users/dkato/code/DisplayApp/ #include "mbed.h" #include "SdUsbConnect.h" #define IMAGE_HW 320 #define IMAGE_VW 240 using namespace cv; /* FACE DETECTOR Parameters */ #define DETECTOR_SCALE_FACTOR (2) #define DETECTOR_MIN_NEIGHBOR (4) #define DETECTOR_MIN_SIZE (30) #define FACE_DETECTOR_MODEL "/storage/lbpcascade_frontalface.xml" static Camera camera(IMAGE_HW, IMAGE_VW); static DisplayApp display_app; static CascadeClassifier detector_classifier; void setup() { pinMode(PIN_LED_GREEN, OUTPUT); pinMode(PIN_LED_RED, OUTPUT); // Camera camera.begin(); // SD & USB SdUsbConnect storage("storage"); storage.wait_connect(); // Load the cascade classifier file detector_classifier.load(FACE_DETECTOR_MODEL); if (detector_classifier.empty()) { digitalWrite(PIN_LED_RED, HIGH); // Error CV_Assert(0); mbed_die(); } } void loop(){ Mat img_raw(IMAGE_VW, IMAGE_HW, CV_8UC2, camera.getImageAdr()); Mat src; cvtColor(img_raw, src, COLOR_YUV2GRAY_YUYV); //covert from YUV to GRAY // Detect a face in the frame Rect face_roi; if (detector_classifier.empty()) { digitalWrite(PIN_LED_RED, HIGH); // Error } // Perform detected the biggest face std::vector<Rect> rect_faces; detector_classifier.detectMultiScale(src, rect_faces, DETECTOR_SCALE_FACTOR, DETECTOR_MIN_NEIGHBOR, CASCADE_FIND_BIGGEST_OBJECT, Size(DETECTOR_MIN_SIZE, DETECTOR_MIN_SIZE)); if (rect_faces.size() > 0) { // A face is detected face_roi = rect_faces[0]; } else { // No face is detected, set an invalid rectangle face_roi.x = -1; face_roi.y = -1; face_roi.width = -1; face_roi.height = -1; } if (face_roi.width > 0 && face_roi.height > 0) { // A face is detected digitalWrite(PIN_LED_GREEN, HIGH); printf("Detected a face X:%d Y:%d W:%d H:%d\n",face_roi.x, face_roi.y, face_roi.width, face_roi.height); digitalWrite(PIN_LED_GREEN, LOW); } else { } Mat dst; cvtColor(img_raw, dst, COLOR_YUV2BGR_YUYV); //covert from YUV to BGR Scalar red(0, 0, 255), green(0, 255, 0), blue(255, 0, 0); rectangle(dst, Point(face_roi.x, face_roi.y), Point(face_roi.x + face_roi.width, face_roi.y + face_roi.height), red, 2); size_t jpegSize = camera.createJpeg(IMAGE_HW, IMAGE_VW, dst.data, Camera::FORMAT_RGB888); display_app.SendJpeg(camera.getJpegAdr(), jpegSize); } |
カスタムファイルの設定
☆SDカードにあるlbpcascade_frontalface.xml
カスタムファイルの取り込みをする
24行目
#define FACE_DETECTOR_MODEL “/storage/lbpcascade_frontalface.xml”
で行う
☆ 物体検出のためのカスケード分類器クラスを宣言
29行目
static CascadeClassifier detector_classifier;
☆カスケードファイルの読み込み
※24行目で宣言したFACE_DETECTOR_MODEL
42行目
// Load the cascade classifier file
detector_classifier.load(FACE_DETECTOR_MODEL);
顔検出
☆グレースケールに変換
※顔認識に用いるデータはグレースケールの為
56行目
cvtColor(img_raw, src, COLOR_YUV2GRAY_YUYV); //covert from YUV to GRAY
☆フレーム内の顔を検出
58行目
// Detect a face in the frame
Rect face_roi;
☆検出した顔をrect_facesに入れる
64行目
// Perform detected the biggest face
std::vector
detector_classifier.detectMultiScale(src, rect_faces,
DETECTOR_SCALE_FACTOR,
DETECTOR_MIN_NEIGHBOR,
CASCADE_FIND_BIGGEST_OBJECT,
Size(DETECTOR_MIN_SIZE, DETECTOR_MIN_SIZE));
☆一番大きいい顔を検出
72行目
if (rect_faces.size() > 0) {
// A face is detected
face_roi = rect_faces[0];
☆顔検出した時の処理
緑LEDを光らせて座標値をシリアルプリント表示。
83行目
if (face_roi.width > 0 && face_roi.height > 0) { // A face is detected
digitalWrite(PIN_LED_GREEN, HIGH);
printf(“Detected a face X:%d Y:%d W:%d H:%d\n”,face_roi.x, face_roi.y, face_roi.width, face_roi.height);
digitalWrite(PIN_LED_GREEN, LOW);
☆カラーにもどす
91行目
cvtColor(img_raw, dst, COLOR_YUV2BGR_YUYV); //covert from YUV to BGR
☆検出した顔に枠を描画する
94行目
rectangle(dst, Point(face_roi.x, face_roi.y), Point(face_roi.x + face_roi.width, face_roi.y + face_roi.height), red, 2);
クラス
通常、cv::Matと記述しクラスを宣言しますが
18行目
using namespace cv;
が記述されてるので Matだけで可能です。
参考資料:OpenCV-CookBook
3件のコメント