【OpenCV】目標檢測

  OpenCV支持的目標檢測的方法是利用樣本的Haar特徵進行的分類器訓練,得到的級聯boosted分類器(Cascade Classification)。haar支持的目標有人臉、眼、嘴、鼻、身體,這裏給出的是臉部和眼部的示例。

  理論參考鏈接:https://docs.opencv.org/master/dc/d88/tutorial_traincascade.html

  代碼參考鏈接:https://docs.opencv.org/master/db/d28/tutorial_cascade_classifier.html


代碼示例

#include "opencv2/objdetect.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

void detectAndDisplay(Mat frame);                       // 檢測並顯示

String face_cascade_name, eyes_cascade_name;
CascadeClassifier face_cascade;                         // 臉部識別
CascadeClassifier eyes_cascade;                         // 眼部識別

String window_name = "Capture - Face detection";

int main(int argc, const char** argv)
{
    CommandLineParser parser(argc, argv,
        "{help h||}"
        "{face_cascade|../data/haarcascade_frontalface_alt.xml|}"
        "{eyes_cascade|../data/haarcascade_eye_tree_eyeglasses.xml|}");
    cout << "\nThis program demonstrates using the cv::CascadeClassifier class "
        "to detect objects (Face + eyes) in a video stream.\n"
        "You can use Haar or LBP features.\n\n";
    parser.printMessage();

    face_cascade_name = parser.get<string>("face_cascade");
    eyes_cascade_name = parser.get<string>("eyes_cascade");

    VideoCapture capture;
    Mat frame;

    // 加載cascades級聯分類器
    if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading face cascade\n"); return -1; };
    if (!eyes_cascade.load(eyes_cascade_name)) { printf("--(!)Error loading eyes cascade\n"); return -1; };

    // 讀取視頻
    capture.open(0);
    if (!capture.isOpened())    { printf(" --(!)Error opening video capture\n"); return -1; }

    while (capture.read(frame))
    {
        if (frame.empty())      { printf(" --(!) No captured frame -- Break!"); break;  }

        // 檢測並顯示
        detectAndDisplay(frame);                        

        char c = (char)waitKey(10);
        if (c == 27) { break; }
    }
    return 0;
}

void detectAndDisplay(Mat frame)
{
    std::vector<Rect> faces;
    Mat frame_gray;

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);        // 轉換灰度圖像
    equalizeHist(frame_gray, frame_gray);               // 直方圖均衡化

    // 檢測臉部
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));

    for (size_t i = 0; i < faces.size(); i++)
    {
        Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);                        // faces矩形的中點

        ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0);// 繪製橢圓

        Mat faceROI = frame_gray(faces[i]);             // ROI

        std::vector<Rect> eyes;

        eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));            // 眼部檢測

        for (size_t j = 0; j < eyes.size(); j++)
        {
            Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2);
            int radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
            circle(frame, eye_center, radius, Scalar(255, 0, 0), 4, 8, 0);
        }
    }

    imshow(window_name, frame);
}

  運行結果就不貼出來了,只是在原有基礎上加了註釋,親測可行(⊙o⊙)!


11/23小更:

  原本計劃是繼續學習OpenCV,後續還會發布SVM等機器學習的內容,但目前還是決定擱置了。在諮詢一畢業數年的博士大牛之後,現在打算開始學習“計算機視覺與機器學習”方向,後續是以python & tensorflow繼續去鑽研這個領域,希望能沉下心去學習研究,不要半途而廢。共勉!


發佈了99 篇原創文章 · 獲贊 210 · 訪問量 40萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章