1. 程式人生 > >OpenCv 之(圖片人臉識別)和 (攝像頭讀入)

OpenCv 之(圖片人臉識別)和 (攝像頭讀入)

先來張人臉識別效果圖:

這裡寫圖片描述

1、概述

人臉識別,是基於人的臉部特徵資訊進行身份識別的一種生物識別技術。用攝像機或攝像頭採集含有人臉的影象或視訊流,並自動在影象中檢測和跟蹤人臉,進而對檢測到的人臉進行臉部的一系列相關技術,通常也叫做人像識別、面部識別。

2、人臉識別步驟

1    人臉影象採集及檢測
2    人臉影象預處理
3    人臉影象特徵提取以及匹配與識別

3、 人臉識別的方法

在OpenCV中主要使用了兩種特徵(即兩種方法)進行人臉檢測,Haar特徵和LBP特徵。使用已經訓練好的XML格式的分類器進行人臉檢測。在OpenCV的安裝目錄下的sources資料夾裡的data資料夾裡可以看到下圖所示的內容(opencv\sources\data\haarcascades ):

這裡寫圖片描述

資料夾的名字“haarcascades”、“hogcascades”和“lbpcascades”分別表示通過“haar”、“hog”和“lbp”三種不同的特徵而訓練出的分類器:"haar"特徵主要用於人臉檢測,“hog”特徵主要用於行人檢測,“lbp”特徵主要用於人臉識別,“eye”特徵主要用於眼睛的檢測識別。

實現人臉檢測主要依賴於detectMultiScale()函式,下面簡單說一下函式引數的含義,先看函式原型:
CV_WRAP virtual void detectMultiScale( const Mat& image,  
                                   CV_OUT vector
<Rect>
& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size() );
各引數含義:
const Mat& image: 需要被檢測的影象(灰度圖)
vector<Rect>& objects: 儲存被檢測出的人臉位置座標序列
double scaleFactor: 每次圖片縮放的比例
int minNeighbors: 每一個人臉至少要檢測到多少次才算是真的人臉
int flags: 決定是縮放分類器來檢測,還是縮放影象
Size(): 表示人臉的最大最小尺寸

4、原始碼分析

(1)檢測圖片中的人臉

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/calib3d/calib3d.hpp>

using namespace std;
using namespace cv;

int main()
{
    Mat image, image_gray;      //定義兩個Mat變數,用於儲存每一幀的影象

    image = imread("F://1.png");
    imshow("原圖", image);

    cvtColor(image, image_gray, CV_BGR2GRAY);//轉為灰度圖
    equalizeHist(image_gray, image_gray);//直方圖均衡化,增加對比度方便處理

    CascadeClassifier eye_Classifier;  //載入分類器
    CascadeClassifier face_cascade;    //載入分類器

    //載入分類訓練器,OpenCv官方文件提供的xml文件,可以直接呼叫
    //xml文件路徑  opencv\sources\data\haarcascades 
    if (!eye_Classifier.load("F:\\haarcascade_eye.xml"))  //需要將xml文件放在自己指定的路徑下
    {  
        cout << "Load haarcascade_eye.xml failed!" << endl;
        return 0;
    }

    if (!face_cascade.load("F:\\haarcascade_frontalface_alt.xml"))
    {
        cout << "Load haarcascade_frontalface_alt failed!" << endl;
        return 0;
    }

    //vector 是個類模板 需要提供明確的模板實參 vector<Rect>則是個確定的類 模板的例項化
    vector<Rect> eyeRect;
    vector<Rect> faceRect;

    //檢測關於眼睛部位位置
    eye_Classifier.detectMultiScale(image_gray, eyeRect, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
    for (size_t eyeIdx = 0; eyeIdx < eyeRect.size(); eyeIdx++)
    {   
        rectangle(image, eyeRect[eyeIdx], Scalar(0, 0, 255));   //用矩形畫出檢測到的位置
    }

    //檢測關於臉部位置
    face_cascade.detectMultiScale(image_gray, faceRect, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
    for (size_t i = 0; i < faceRect.size(); i++)
    {   
        rectangle(image, faceRect[i], Scalar(0, 0, 255));      //用矩形畫出檢測到的位置
    }

    imshow("人臉識別圖", image);         //顯示當前幀
    waitKey(0);

}

return 0;
}

(2)檢測攝像頭中的人臉

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/calib3d/calib3d.hpp>

using namespace std;
using namespace cv;

int main()
{
    Mat image, image_gray;      //定義兩個Mat變數,用於儲存每一幀的影象
    VideoCapture capture(0);    //從攝像頭讀入視訊

    while (1)                  //迴圈顯示每一幀
    {
        capture >> image;     //讀取當前幀

        //image = imread("F://1.png");
        //imshow("原圖", image);

        cvtColor(image, image_gray, CV_BGR2GRAY);//轉為灰度圖
        equalizeHist(image_gray, image_gray);//直方圖均衡化,增加對比度方便處理

        CascadeClassifier eye_Classifier;  //載入分類器
        CascadeClassifier face_cascade;    //載入分類器

        //載入分類訓練器,OpenCv官方文件提供的xml文件,可以直接呼叫
        //xml文件路徑  opencv\sources\data\haarcascades 
        if (!eye_Classifier.load("F:\\haarcascade_eye.xml"))  //需要將xml文件放在自己指定的路徑下
        {  
            cout << "Load haarcascade_eye.xml failed!" << endl;
            return 0;
        }

        if (!face_cascade.load("F:\\haarcascade_frontalface_alt.xml"))
        {
            cout << "Load haarcascade_frontalface_alt failed!" << endl;
            return 0;
        }

        //vector 是個類模板 需要提供明確的模板實參 vector<Rect>則是個確定的類 模板的例項化
        vector<Rect> eyeRect;
        vector<Rect> faceRect;

        //檢測關於眼睛部位位置
        eye_Classifier.detectMultiScale(image_gray, eyeRect, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));//檢測
        for (size_t eyeIdx = 0; eyeIdx < eyeRect.size(); eyeIdx++)
        {   
            rectangle(image, eyeRect[eyeIdx], Scalar(0, 0, 255));   //用矩形畫出檢測到的位置
        }

        //檢測關於臉部位置
        face_cascade.detectMultiScale(image_gray, faceRect, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));//檢測
        for (size_t i = 0; i < faceRect.size(); i++)
        {   
            rectangle(image, faceRect[i], Scalar(0, 0, 255));      //用矩形畫出檢測到的位置
        }

        imshow("人臉識別圖", image);         //顯示當前幀
        char c = waitKey(30);         //延時30ms,即每秒播放33幀影象
        if (c == 27)  break;    
    }

    return 0;
}

效果圖:
這裡寫圖片描述