0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RaspberryPiで顔検出

Posted at

はじめに

こちらはRaspberry Pi と LINE messaging API で作る監視カメラシリーズ第5弾です。

今回はOpenCV を使って10秒間の動画を撮りながら、顔を検知したら顔を緑色の枠で囲むコードになります。

顔検出のパラメータを調整してちょうど良い値を見つけてみてください。

また、ここではシリーズ第2弾「ラズパイ監視カメラに使用したライブラリなどのインストール」でダウンロードした顔の学習済みデータファイルhaarcascade_frontalface_default.xmlを使用します、OpenCVの顔検出機能に使用するデータファイルのダウンロードをご覧ください。

顔検出のコードです。

line_botディレクトリに移動し

cd /home/pi/projects/line_bot

main.cppを作成します

vim main.cpp

テキストエディタに次のコードを貼り付けます。

main.cpp
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {

    // 1. 顔検出器の初期化
    CascadeClassifier face_detector;
    string cascade_path = "haarcascade_frontalface_default.xml"; // ダウンロードしたXMLファイルのパスを指定。実行ファイルと同じディレクトリに置くか、絶対パスを指定してください。
    
    if (!face_detector.load(cascade_path)) {
        cerr << "エラー: 顔カスケードファイルを読み込めませんでした: " << cascade_path << endl;
        cerr << "'haarcascade_frontalface_default.xml' が実行可能ファイルと同じディレクトリにあること、または絶対パスがパスが合っていることを確認してください。" << endl;
        return -1;
    }
    cout << "顔カスケードファイルが正常に読み込まれました。" << endl;

    // 2. VideoCaptureオブジェクトの初期化
    VideoCapture cap(0); 

    if (!cap.isOpened()) {
        cerr << "エラー: カメラを開けませんでした。" << endl;
        return -1;
    }
    
    // 3. 動画設定の取得 (解像度、FPS)
    int frame_width = static_cast<int>(cap.get(CAP_PROP_FRAME_WIDTH));
    int frame_height = static_cast<int>(cap.get(CAP_PROP_FRAME_HEIGHT));
    Size frame_size(frame_width, frame_height);
    double fps = 30.0; // 録画FPS

    
    // 4. VideoWriterオブジェクトの初期化 (録画ファイル設定)
    VideoWriter writer("faces.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, frame_size);

    if (!writer.isOpened()) {
        cerr << "エラー: Video Writerを開けませんでした。" << endl;
        return -1;
    }
    
    cout << "Video Writerを初期化しました。顔検出機能を使って10秒間録画を開始します..." << endl;

    Mat frame;
    Mat gray_frame; // 顔検出はグレースケール画像で行うため
    vector<Rect> faces; // 検出された顔の矩形を格納するベクトル
    
    int frame_count = 0;
    const int max_frames = static_cast<int>(fps * 10); // 10秒間の録画

   
    // 5. メインループ: フレーム取得 -> 検出 -> 描画 -> 録画
    while (frame_count < max_frames) {
        
        if (!cap.read(frame)) {
            cerr << "警告: ビデオ ストリームからフレームを読み取ることができません。終了します。" << endl;
            break;
        }

        // --- 顔検出処理 ---
        // BGRフレームをグレースケールに変換 (Haar Cascadeはグレースケールで動作)
        cvtColor(frame, gray_frame, COLOR_BGR2GRAY);
        // 顔検出の実行
        face_detector.detectMultiScale(gray_frame, faces, 1.1, 7, 0, Size(60, 60)); 
        // パラメータ:ここで検出精度をざっくり調整する
        //  1.1: スケールファクター。画像をどれだけ縮小して検出を行うか (1.05~1.4程度)小さいほど精度が高いが処理速度が長くなる
        //  5: minNeighbors。矩形が何回検出されたら顔とみなすか (3~6程度)高いほど誤検出は減るが、検出漏れが増える可能性がある。
        //  0: flags。古いOpenCVとの互換性用
        //  Size(30, 30): minSize。検出する最小の顔サイズ (小さすぎると誤検出が増える)大きくすると小さすぎるノイズを顔と検出する誤検知が防げる。
      

        // 検出された顔に緑色の枠を描画
        for (const auto& face : faces) {
            rectangle(frame, face, Scalar(0, 255, 0), 2); // 緑色の2ピクセル幅の枠
        }
        
        // 描画されたフレームをファイルに書き込む
        writer.write(frame);
        
        cout << "Recording Frame " << frame_count + 1 << "/" << max_frames 
             << " (顔を検出した数: " << faces.size() << ")" << endl;
        
        frame_count++;
    }

    // 6. ループ終了。オブジェクトの解放
    cap.release();
    writer.release(); 
    
    cout << "録画完了:ファイルはfaces.aviとして保存されました。" << endl;

    return 0;
}


ESCキーを押して、:wqを入力してEnterで保存して閉じます。

buildディレクトリに移動し、

cd build

makeコマンドでビルドします。

make

実行ファイルのmain_appが生成されていますので./で実行します。

./main_app

buildディレクトリ内にfaces.aviが生成されているので確認してみてください。

scpコマンドでPCにコピーする方法は下記を参考にどうぞ。

さいごに

顔検出の精度についてはコード内に記載したパラメータが私的に落ち着いた値になります。
照度なども検出精度に影響するので実際に使用する場所でパラメータを調整する必要があります。
今回は簡単な検知でLINEに通知する目的のため試しませんでしたが、そのうちディープラーニングベースの人間検出で精度の高い検出機能を作ってみたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?