自分だけのクイズを作成しよう - Quipha
スポンサーリンク

【OpenCvSharp】画像の顔や体などの物体検出

OpenCV

当サイトではアフィリエイト広告を利用しています。

スポンサーリンク

はじめに

今回は、OpenCvSharpを使い、画像の中の顔や体などを検出してみたいと思います。

OpenCvSharpのインストールや、サンプルアプリの作成は以下の記事を参考にしてください。

Visual Studio 2022のインストールにつきましては、以下の記事にまとめましたので参考ください。

また、本技術を簡単に確認できるようなアプリを作成しました。
ソースコードも公開しており、アプリでは物体検出の精度を簡単に確認することができます。

使用するバージョン
  • Windows 11 / 10
  • Visual Studio 2022 (2019)

カスケード分類器の用意

概要

OpenCVには、画像の中の物体検出を行う機能があります。
例えば、「顔はこういうもの」と学習したデータをカスケード分類器と呼ばれます。

自分で作成することもできますが、今回はOpenCVで用意されているカスケード分類器を使用します。

以下にXMLファイルが用意されていますので、以降で試してみましょう。

https://github.com/opencv/opencv/tree/master/data/haarcascades

カスケード分類器一覧

カスケード分類器概要
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上半身
スポンサーリンク

顔検出

サンプル画像の用意

人の顔が写っている画像を用意します。
以下のフリー素材を使用させていただきました。

仲良し2
仲良し2(No: 3214135)の無料写真素材を提供する「写真AC」のフリー写真素材は、個人、商用を問わず無料でお使いいただけます。クレジット表記やリンクは一切不要です。Web、DTP、動画などの写真素材としてお使いください。

以下の場所に画像を保存しました。

D:\project\img\face1.jpg

物体検出

まずは、正面の顔を検出してみましょう。
以下にアクセスし、カスケード分類器をダウンロードします。

https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_default.xml

画面上の「Raw」ボタンをクリックします。

テキスト画面が開きますので、Ctrl+Sでファイルに名前をつけて保存します。

XMLファイルは任意の場所に保存します。
私は以下の場所に保存しました。

D:\project\haarcascades\haarcascade_frontalface_default.xml

適当なボタンをフォームに配置し、ボタンのクリックイベントに処理を実装します。
ダウンロードしたカスケード分類器のパスを指定しています。

private void button3_Click(object sender, EventArgs e)
{
    // 画像とカスケード分類器の読み込み
    using (var mat = new Mat(@"D:\project\img\face1.jpg"))
    using (var cascade = new CascadeClassifier(@"D:\project\haarcascades\haarcascade_frontalface_default.xml"))
    {
        // 検出
        foreach (Rect rectDetect in cascade.DetectMultiScale(mat))
        {
            // 枠を表示
            Rect rect = new Rect(rectDetect.X, rectDetect.Y, rectDetect.Width, rectDetect.Height);
            Cv2.Rectangle(mat, rect, new OpenCvSharp.Scalar(255, 255, 0), 2);
        }

        Cv2.ImShow("image", mat);
    }
}

実行してみましょう。
正しく顔が検出されました。

正面の顔については、他にもhaarcascade_frontalface_alt.xmlなど4つありますが、それぞれで検出する精度が違うようです。
顔検出がうまくいかない場合は、他のも試すと良いでしょう。

目の検出

次に、目の検出を試してみましょう。
先ほどと同様の手順で、haarcascade_eye.xmlをダウンロードします。

コードは以下です。カスケード分類器の指定が違うだけで、処理は同じです。

private void button4_Click(object sender, EventArgs e)
{
    // 画像とカスケード分類器の読み込み
    using (var mat = new Mat(@"D:\project\img\face1.jpg"))
    using (var cascade = new CascadeClassifier(@"D:\project\haarcascades\haarcascade_eye.xml"))
    {
        // 検出
        foreach (Rect rectDetect in cascade.DetectMultiScale(mat))
        {
            // 枠を表示
            Rect rect = new Rect(rectDetect.X, rectDetect.Y, rectDetect.Width, rectDetect.Height);
            Cv2.Rectangle(mat, rect, new OpenCvSharp.Scalar(255, 255, 0), 2);
        }

        Cv2.ImShow("image", mat);
    }
}

実行してみると、誤検知していました・・😅

メガネをしている目の検出

次は、メガネをしている目を検出してみます。(メガネをしていない目も検出しました)
以下のフリー素材を使用しました。

メガネをかけた女性
メガネをかけた女性(No: 4061271)の無料写真素材を提供する「写真AC」のフリー写真素材は、個人、商用を問わず無料でお使いいただけます。クレジット表記やリンクは一切不要です。Web、DTP、動画などの写真素材としてお使いください。

haarcascade_eye_tree_eyeglasses.xmlをダウンロードします。
コードは以下です。

private void button5_Click(object sender, EventArgs e)
{
    // 画像とカスケード分類器の読み込み
    using (var mat = new Mat(@"D:\project\img\face2.jpg"))
    using (var cascade = new CascadeClassifier(@"D:\project\haarcascades\haarcascade_eye_tree_eyeglasses.xml"))
    {
        // 検出
        foreach (Rect rectDetect in cascade.DetectMultiScale(mat))
        {
            // 枠を表示
            Rect rect = new Rect(rectDetect.X, rectDetect.Y, rectDetect.Width, rectDetect.Height);
            Cv2.Rectangle(mat, rect, new OpenCvSharp.Scalar(255, 255, 0), 2);
        }

        Cv2.ImShow("image", mat);
    }
}

メガネをしていても、正しく目を検出できました。

体の検出

体の検出をしてみます。
以下のフリー素材を使用しました。

秋の公園で遊ぶ家族・ファミリー
秋の公園で遊ぶ家族・ファミリー(No: 4401722)の無料写真素材を提供する「写真AC」のフリー写真素材は、個人、商用を問わず無料でお使いいただけます。クレジット表記やリンクは一切不要です。Web、DTP、動画などの写真素材としてお使い...

haarcascade_fullbody.xmlをダウンロードします。
コードは以下です。

// 画像とカスケード分類器の読み込み
using (var mat = new Mat(@"D:\project\img\body1.jpg"))
using (var cascade = new CascadeClassifier(@"D:\project\haarcascades\haarcascade_fullbody.xml"))
{
    // 検出
    foreach (Rect rectDetect in cascade.DetectMultiScale(mat))
    {
        // 枠を表示
        Rect rect = new Rect(rectDetect.X, rectDetect.Y, rectDetect.Width, rectDetect.Height);
        Cv2.Rectangle(mat, rect, new OpenCvSharp.Scalar(255, 255, 0), 2);
    }

    Cv2.ImShow("image", mat);
}

体を検出しました。

猫の検出

折角なので最後に、猫の顔を検出します。
以下のフリー素材を使用しました。

ベンガル猫とサバトラ猫_仲良し
ベンガル猫とサバトラ猫_仲良し(No: 4571939)の無料写真素材を提供する「写真AC」のフリー写真素材は、個人、商用を問わず無料でお使いいただけます。クレジット表記やリンクは一切不要です。Web、DTP、動画などの写真素材としてお使い...

haarcascade_frontalcatface.xmlをダウンロードします。
コードは以下です。

private void button7_Click(object sender, EventArgs e)
{
    // 画像とカスケード分類器の読み込み
    using (var mat = new Mat(@"D:\project\img\cat.jpg"))
    using (var cascade = new CascadeClassifier(@"D:\project\haarcascades\haarcascade_frontalcatface.xml"))
    {
        // 検出
        foreach (Rect rectDetect in cascade.DetectMultiScale(mat))
        {
            // 枠を表示
            Rect rect = new Rect(rectDetect.X, rectDetect.Y, rectDetect.Width, rectDetect.Height);
            Cv2.Rectangle(mat, rect, new OpenCvSharp.Scalar(255, 255, 0), 2);
        }

        Cv2.ImShow("image", mat);
    }
}

一匹だけ検出しました。🙂

さいごに

OpenCVが用意している、カスケード分類器を使用して、画像の物体検出を行いました。
カスケード分類器は自作することもできるので、さらに精度を上げたいとか、特殊な検出もできるかも知れませんね。

お疲れさまでした。😊

他にも私のブログで、OpenCVについて解説している記事がありますのでご覧ください。

\オススメ/

コメント