「計算機視覺C++」C++實現人臉識別

dl小寶 發佈 2020-03-13T01:43:16+00:00

比如算法精確度上,國內國外的人臉識別技術大多數在開源OpenCV等開源庫上進行新規則添加,公司之間的識別正確率差異僅僅在小數點上,99.6%-99.7%提升意義不大,如果說就此稱王稱霸就說達到世界一流,就要被內行笑話了。

1.介紹

人臉識別是圖像處理非常重要的應用之一。本文這是一個簡單的人臉識別程序,運用OpenCV3中自帶的模型:(需要模型文件的私信我喔!)

haarcascade_frontalface_alt.xml
haarcascade_eye_tree_eyeglasses.xml

2.幾句牢騷話

人臉識別技術的衡量維度太多,但從技術比較,比如圖像比對級的1:1,1:N,N:N。衡量的標準和維度都不同。比如算法精確度上,國內國外的人臉識別技術大多數在開源OpenCV等開源庫上進行新規則添加(深度學習進行疊層運算),公司之間的識別正確率差異僅僅在小數點上,99.6%-99.7%提升意義不大,如果說就此稱王稱霸就說達到世界一流,就要被內行笑話了。基本上國內每家公司都會說自己的人臉識別算法牛,真正表達的是缺乏對底層技術的敬畏。

3.C++的人臉識別實現

//--------------------------------------【程序說明】-------------------------------------------
//              程序描述:人臉識別
//              測試所用作業系統: Windows 10 64bit
//              測試所用IDE版本:Visual Studio 2017
//              測試所用OpenCV版本:   3.4
//              2020年3月 Revised by @DL小寶
//------------------------------------------------------------------------------------------------

/**
 * @file ObjectDetection.cpp
 * @author A. Huaman ( based in the classic facedetect.cpp in samples/c )
 * @brief A simplified version of facedetect.cpp, show how to load a cascade classifier and how to find objects (Face + eyes) in a video stream
 */

 //---------------------------------【頭文件、命名空間包含部分】----------------------------
 //             描述:包含程序所使用的頭文件和命名空間
 //-------------------------------------------------------------------------------------------------
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

void detectAndDisplay(Mat frame);

//--------------------------------【全局變量聲明】----------------------------------------------
//              描述:聲明全局變量
//-------------------------------------------------------------------------------------------------
//注意,需要把"haarcascade_frontalface_alt.xml"和"haarcascade_eye_tree_eyeglasses.xml"這兩個文件複製到工程路徑下
String face_cascade_name = "haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
string window_name = "Capture - Face detection";
RNG rng(12345);

//--------------------------------【help( )函數】----------------------------------------------
//              描述:輸出幫助信息
//-------------------------------------------------------------------------------------------------
static void ShowHelpText()
{
        //輸出歡迎信息和OpenCV版本
        cout << "\n\n\t\t\t   當前使用的OpenCV版本為:" << CV_VERSION
                << "\n\n  ----------------------------------------------------------------------------";
}

//-----------------------------------【main( )函數】--------------------------------------------
//              描述:控制台應用程式的入口函數,我們的程序從這裡開始
//-------------------------------------------------------------------------------------------------
int main(void)
{
        VideoCapture capture;
        Mat frame;

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

        //-- 2. 讀取視頻
        capture.open(0);
        ShowHelpText();
        if (capture.isOpened())
        {
                for (;;)
                {
                        capture >> frame;

                        //-- 3. 對當前幀使用分類器(Apply the classifier to the frame)
                        if (!frame.empty())
                        {
                                detectAndDisplay(frame);
                        }
                        else
                        {
                                printf(" --(!) No captured frame -- Break!"); break;
                        }

                        int c = waitKey(10);
                        if ((char)c == 'c') { 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);

        //-- 人臉檢測
        //此句代碼的OpenCV2版為:
   //face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
        //此句代碼的OpenCV3版為:
        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);
                ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 2, 8, 0);

                Mat faceROI = frame_gray(faces[i]);
                std::vector<Rect> eyes;

                //-- 在臉中檢測眼睛
                //此句代碼的OpenCV2版為:
           // eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
                //此句代碼的OpenCV3版為:
                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), 3, 8, 0);
                }
        }
        //-- 顯示最終效果圖
        imshow(window_name, frame);
}
關鍵字: