OpenCv 之(圖片人臉識別)和 (攝像頭讀入)
阿新 • • 發佈:2018-12-30
先來張人臉識別效果圖:
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;
}
效果圖: