對人類來說,人臉識別很容易僅僅是才三天的嬰兒已經(jīng)可以區(qū)分周圍熟悉的人臉了。那么對于計算機(jī)來說,到底有多難?其實,迄今為止,我們對于人類自己為何可以區(qū)分不同的人所知甚少。是人臉內(nèi)部特征(眼睛、鼻子、嘴巴)還是外部特征(頭型、發(fā)際線)對于人類識別更有效?
自動人臉識別就是如何從一幅圖像中提取有意義的特征,把它們放入一種有用的表示方式,然后對他們進(jìn)行一些分類。基于幾何特征的人臉的人臉識別可能是最直觀的方法來識別人臉。
人臉識別的第一步,就是人臉檢測。把人的臉部從一張照片中用計算機(jī)自動識別出來,作為下一步人臉識別的基礎(chǔ)。
在opencv中,庫中自帶了一個利用harr特征的人臉檢測訓(xùn)練及檢測函數(shù):cvHaarDetectObjects。它利用訓(xùn)練好的檢測器,在圖片中間檢測你想要的物體,如人臉。opencv自帶了很多檢測器,在%opencv%data/haarcascades目錄下,你可以隨意取用。或者你也可以自己用圖片訓(xùn)練自己的檢測器,之后拿來使用。
如何來用OpenCV來實現(xiàn)能。
下面給出OpenCV實現(xiàn)人臉檢測的一般步驟:
1.加載人臉檢測器
2.開啟攝像頭
3.對圖片進(jìn)行灰度處理(其實可以不處理,上圖中原圖的標(biāo)題欄就是未進(jìn)行灰度處理進(jìn)行的檢測,這里的灰度是為下節(jié)人臉識別打基礎(chǔ))
4.對圖片進(jìn)行直方圖均衡化(其實可以不處理,上圖中原圖的標(biāo)題欄就是未進(jìn)行灰度處理進(jìn)行的檢測和灰度圖是為進(jìn)行均衡化識別,這里的均衡化是為下節(jié)人臉識別打基礎(chǔ))
5.人臉檢測
總結(jié)下,如果單單只要人臉檢測,可以的步驟是1,2,5
程序截圖如下:
下面是完整的代碼,本代碼還有大量注釋,在此不再具體說明哪個函數(shù)有什么用。
?
[cpp] view plain copy#include 《opencv.hpp》
#include 《opencv2/core/core.hpp》
#include 《iostream》
using namespace cv;
void Pic2Gray(Mat camerFrame,Mat &gray)
{
//普通臺式機(jī)3通道BGR,移動設(shè)備為4通道
if (camerFrame.channels() == 3)
{
cvtColor(camerFrame, gray, CV_BGR2GRAY);
}
else if (camerFrame.channels() == 4)
{
cvtColor(camerFrame, gray, CV_BGRA2GRAY);
}
else
gray = camerFrame;
}
int main()
{
//加載Haar或LBP對象或人臉檢測器
CascadeClassifier faceDetector;
std::string faceCascadeFilename = “haarcascade_frontalface_default.xml”;
//友好錯誤信息提示
try{
faceDetector.load(faceCascadeFilename);
}
catch (cv::Exception e){}
if (faceDetector.empty())
{
std::cerr 《《 “臉部檢測器不能加載 (”;
std::cerr 《《 faceCascadeFilename 《《 “)!” 《《 std::endl;
exit(1);
}
//打開攝像頭
VideoCapture camera(0);
while (true)
{
Mat camerFrame;
camera 》》 camerFrame;
if (camerFrame.empty())
{
std::cerr 《《 “無法獲取攝像頭圖像” 《《 std::endl;
getchar();
exit(1);
}
Mat displayedFrame(camerFrame.size(),CV_8UC3);
//人臉檢測只試用于灰度圖像
Mat gray;
Pic2Gray(camerFrame, gray);
//直方圖均勻化(改善圖像的對比度和亮度)
Mat equalizedImg;
equalizeHist(gray, equalizedImg);
//人臉檢測用Cascade Classifier::detectMultiScale來進(jìn)行人臉檢測
int flags = CASCADE_FIND_BIGGEST_OBJECT|CASCADE_DO_ROUGH_SEARCH; //只檢測臉最大的人
//int flags = CASCADE_SCALE_IMAGE; //檢測多個人
Size minFeatureSize(30, 30);
float searchScaleFactor = 1.1f;
int minNeighbors = 4;
std::vector《Rect》 faces;
faceDetector.detectMultiScale(equalizedImg, faces, searchScaleFactor, minNeighbors, flags, minFeatureSize);
//畫矩形框
cv::Mat face;
cv::Point text_lb;
for (size_t i = 0; i 《 faces.size(); i++)
{
if (faces[i].height 》 0 && faces[i].width 》 0)
{
face = gray(faces[i]);
text_lb = cv::Point(faces[i].x, faces[i].y);
cv::rectangle(equalizedImg, faces[i], cv::Scalar(255, 0, 0), 1, 8, 0);
cv::rectangle(gray, faces[i], cv::Scalar(255, 0, 0), 1, 8, 0);
cv::rectangle(camerFrame, faces[i], cv::Scalar(255, 0, 0), 1, 8, 0);
}
}
imshow(“直方圖均勻化”, equalizedImg);
imshow(“灰度化”, gray);
imshow(“原圖”, camerFrame);
waitKey(20);
}
getchar();
return 0;
}
評論
查看更多