【Visual Studio】 OpenCV에서 Haar-like 특징 분류기를 이용한 오브젝트 검출

15321 단어 C++VisualStudioOpenCV

소개



※이것은, VC++ Visual Studio를 이용하는 초보자용의 학습용 기사입니다.

이번에는 Visual Studio를 이용하여 화상 처리 라이브러리 OpenCV를 이용하여 Haar-like 특징 분류기를 이용한 오브젝트 검출을 설명한다.
Haar-like 특징 분류기를 이용한 인식은 객체 검출이라고도 합니다.
Haar-like 특징 분류기를 변경하여 탐지하려는 얼굴과 물체를 탐지할 수 있습니다.
OpenCV 4.0.0을 사용하고 있습니다.

OpenCV에서 Haar-like 특징 분류기의 함수



OpenCV에서 Haar-like 특징 분류기를 사용하는 방법은 다음 변수 유형과 두 가지 함수를 사용합니다.
cv::CascadeClassifier::CascadeClassifier(const String &filename)

첫 번째 함수는 Haar-like 특징 분류기를 선언하는 변수 유형과 함수입니다.
void cv::CascadeClassifier::detectMultiScale(
    InputArray image,
    std::vector<Rect> &objects,
    double  scaleFactor = 1.1,
    int     minNeighbors = 3,
    int     flags = 0,
    Size    minSize = Size(),
    Size    maxSize = Size() 
)   

두 번째 함수는 Haar-like 특징 분류기를 사용하여 객체를 감지하는 함수입니다.

Haar-like 특징 분류기 선언 및 분류기 사용법
cv::CascadeClassifier cascadeclassifier("cascade_filename.xml");
//cascadeclassifier:変数宣言です
//"cascade_filename.xml":String型:カスケードファイル[.xml]を読み込むファイル名をしています。

cv::CascadeClassifier cascadeclassifier;        //先に宣言する場合
cascadeclassifier.load("cascade_filename.xml"); //カスケードファイル[.xml]を読み込むファイル名をしています。

cascadeclassifier.detectMultiScale(src_gray, objects, 1.3, 3, CASCADE_SCALE_IMAGE, Size(50, 50), Size(150, 150));
//cascadeclassifier:オブジェクトの識別変数:宣言時にカスケードファイル[.xml]と呼ばれる識別ファイルを読み込みます。
//src_gray:Mat型:入力画像 Haar-like特徴分類器では、1チャンネルのグレースケール画像のみ入力可能です。(CV_8U, CV_8UC1)
//objects:std::vector<Rect>:検出されたオブジェクトの位置と範囲が格納されます。
//1.3:double型:検出するサイズを拡大縮小するときの拡大率。
//3:int型:オブジェクトを検出した際に、領域の重なりがこの数値以上であれば検出とする。
//CASCADE_SCALE_IMAGE:int型(定義値使用):現在は利用されてないそうです。定値と思ってください。
//Size(50, 50):Size型:最小の検出サイズです。
//Size(150, 150):Size型:最大の検出サイズで。

detectMultiScale은 입력 화상과 출력처의 std::vector는 필요합니다만, 그 이후의 값은 초기치가 설정되어 있으므로 없이도 괜찮습니다. 그러나 발견되지 않으면 설정을 변경해야 합니다.

detectMultiScale 정보
cascadeclassifier.detectMultiScale(src_gray, objects); //これでも動く

계단식 파일 [.xml] 정보



OpenCV는 학습된 계단식 파일 [.xml]을 제공하므로 이를 활용하여 쉽게 검색할 수 있습니다.
계단식 파일은 OpneCV 설치 디렉토리에서 "build"- "etc"- "haarcascades"에 저장됩니다.
캐스케이드 파일의 절대 경로를 사용하거나 이미지를 로드할 위치와 함께 위치에 복사하여 사용합니다.
다음은 계단식 파일 이름과 그 검색 내용의 발췌를 보여줍니다.


계단식 파일 이름
검출 내용


haarcascade_frontalface_alt2.xml
얼굴(정면)

haarcascade_fullbody.xml
전신


Haar-like 특징 분류기를 이용한 객체 검출 테스트 프로그램



haarlike_Test1.cpp
#include <opencv2/opencv.hpp>

#ifdef _DEBUG
#pragma comment(lib, "opencv_world400d.lib")
#else
#pragma comment(lib, "opencv_world400.lib")
#endif

using namespace std;
using namespace cv;

int main()
{
    Mat src = imread("src.png");                                        //識別したい画像を読み込む
    Mat src_gray;                                                       //グレースケール画像変換用変数
    vector<Rect> objects;                                               //検出結果出力用

    cvtColor(src, src_gray, COLOR_BGR2GRAY);                            //読み込んだ画像をグレースケール画像にする

    cv::CascadeClassifier cascadeclassifier("haarcascade_frontalface_alt2.xml");    //カスケードファイル[.xml]を読み込み識別器を宣言する
    //cv::CascadeClassifier cascadeclassifier("C:\opencv4.0.0\opencv\build\etc\haarcascades\haarcascade_frontalface_alt2.xml");
    //例:カスケードファイル[.xml]を絶対パスで読み込み識別器を宣言する

    cascadeclassifier.detectMultiScale(src_gray, objects, 1.1, 2, CASCADE_SCALE_IMAGE, Size(70, 70), Size(150, 150));    //検出する

    vector<Rect>::iterator itr;                                         //vector内のデータを検索するためのイテレータ
    for (itr = objects.begin(); itr != objects.end(); itr++) {
        rectangle(src, Point(itr->x, itr->y), Point(itr->x + itr->width, itr->y + itr->height), Scalar(0, 0, 255), 3, LINE_AA);
        //元画像の検出した顔の領域を赤色の矩形で囲む

        cout << "検出: 座標:" << Point(itr->x, itr->y) << " サイズ:" << Size(itr->width, itr->height) << endl;
    }

    /*
    //イテレータの使い方がわからない人はこちら
    for (int i = 0; i < objects.size(); i++) {
        rectangle(src, Point(objects[i].x, objects[i].y), Point(objects[i].x + objects[i].width, objects[i].y + objects[i].height), Scalar(0, 0, 255), 3, LINE_AA);
        //元画像の検出した顔の領域を赤色の矩形で囲む

        cout << "検出: 座標:" << Point(objects[i].x, objects[i].y) << " サイズ:" << Size(objects[i].width, objects[i].height) << endl;
    }
    */

    imshow("src", src);                                                 //元画像表示
    waitKey();

    return 0;
}



출력 결과
検出: 座標:[53, 33] サイズ:[95 x 95]
検出: 座標:[243, 440] サイズ:[103 x 103]
検出: 座標:[52, 233] サイズ:[119 x 119]
検出: 座標:[56, 624] サイズ:[126 x 126]

샘플이므로 정확도가 나쁘다.
사람의 얼굴 사진 등으로하면 정밀도가 좋다고 생각합니다.

Haar-like 특징 분류기의 읽기 확인 함수



Haar-like 특징 분류기를 선언하고 캐스케이드 파일 [.xml]을 읽은 후 올바르게 읽을 수 있는지 확인하는 함수가 있습니다.

Haar-like 특징 분류기의 로딩 확인
bool cv::CascadeClassifier::empty();

empty()는 반환값이 bool형이며, True이면 읽을 수 없는 상태. False이면 읽을 수 있다고 확인이 가능하다.
캐스케이드 파일이 올바르게 읽히지 않고 검출 처리를 실행하면 Assertion failed의 원인이되므로 반드시 확인을하는 것이 무난하다.

Haar-like 특징 분류기 로딩 확인 프로그램



haarlike_Test2.cpp
#include <opencv2/opencv.hpp>

#ifdef _DEBUG
#pragma comment(lib, "opencv_world400d.lib")
#else
#pragma comment(lib, "opencv_world400.lib")
#endif

using namespace std;
using namespace cv;

int main()
{
    cv::CascadeClassifier cascadeclassifier("haarcascade_frontalface_alt2.xml");    //カスケードファイル[.xml]を読み込み識別器を宣言する

    if (cascadeclassifier.empty()) {                                                //カスケードファイル読み込みの確認
        cout << "Cascade file Not Loaded!" << endl;                                 //読み込みできてない場合はエラー
        return -1;                                                                  //プログラム終了
    }

    return 0;
}

주의점



캐스케이드 파일을 올바르게 읽지 않으면 감지시 오류가 발생합니다.

사이고에게



이번에는 Visual Studio를 이용하여 화상 처리 라이브러리 OpenCV를 이용하여 Haar-like 특징 분류기를 이용한 오브젝트 검출을 실시했다.
이번 이용한 함수의 인수가 갑자기 많아졌으므로 혼란하는 사람도 많다고 생각합니다.
또, 임계치가 사이즈나 확대 축소의 파라미터, 직사각형의 근방수 등 복수의 임계치도 설정해야 하고,
잘 검출할 수 없는 경우가 많다고 생각합니다.

여담:
자작의 캐스케이드 파일의 작성 방법도 기사에 정리해 두는 편이 좋네요. 원하는 사람이 있습니까?
심층 학습이 주로 되어 온 지금, Haar-like 특징 분류기의 정밀도를 유지하는 것은 어렵습니다만. .

좋은 웹페이지 즐겨찾기