對(duì)人類來說,人臉識(shí)別很容易僅僅是才三天的嬰兒已經(jīng)可以區(qū)分周圍熟悉的人臉了。那么對(duì)于計(jì)算機(jī)來說,到底有多難?其實(shí),迄今為止,我們對(duì)于人類自己為何可以區(qū)分不同的人所知甚少。是人臉內(nèi)部特征(眼睛、鼻子、嘴巴)還是外部特征(頭型、發(fā)際線)對(duì)于人類識(shí)別更有效?
自動(dòng)人臉識(shí)別就是如何從一幅圖像中提取有意義的特征,把它們放入一種有用的表示方式,然后對(duì)他們進(jìn)行一些分類?;趲缀翁卣鞯娜四樀娜四樧R(shí)別可能是最直觀的方法來識(shí)別人臉。
人臉識(shí)別的第一步,就是人臉檢測(cè)。把人的臉部從一張照片中用計(jì)算機(jī)自動(dòng)識(shí)別出來,作為下一步人臉識(shí)別的基礎(chǔ)。
在opencv中,庫(kù)中自帶了一個(gè)利用harr特征的人臉檢測(cè)訓(xùn)練及檢測(cè)函數(shù):cvHaarDetectObjects。它利用訓(xùn)練好的檢測(cè)器,在圖片中間檢測(cè)你想要的物體,如人臉。opencv自帶了很多檢測(cè)器,在%opencv%data/haarcascades目錄下,你可以隨意取用?;蛘吣阋部梢宰约河脠D片訓(xùn)練自己的檢測(cè)器,之后拿來使用。
如何來用OpenCV來實(shí)現(xiàn)能。
下面給出OpenCV實(shí)現(xiàn)人臉檢測(cè)的一般步驟:
1.加載人臉檢測(cè)器
2.開啟攝像頭
3.對(duì)圖片進(jìn)行灰度處理(其實(shí)可以不處理,上圖中原圖的標(biāo)題欄就是未進(jìn)行灰度處理進(jìn)行的檢測(cè),這里的灰度是為下節(jié)人臉識(shí)別打基礎(chǔ))
4.對(duì)圖片進(jìn)行直方圖均衡化(其實(shí)可以不處理,上圖中原圖的標(biāo)題欄就是未進(jìn)行灰度處理進(jìn)行的檢測(cè)和灰度圖是為進(jìn)行均衡化識(shí)別,這里的均衡化是為下節(jié)人臉識(shí)別打基礎(chǔ))
5.人臉檢測(cè)
總結(jié)下,如果單單只要人臉檢測(cè),可以的步驟是1,2,5
程序截圖如下:
下面是完整的代碼,本代碼還有大量注釋,在此不再具體說明哪個(gè)函數(shù)有什么用。
?
?。踓pp] view plain copy#include 《opencv.hpp》
#include 《opencv2/core/core.hpp》
#include 《iostream》
using namespace cv;
void Pic2Gray(Mat camerFrame,Mat &gray)
{
//普通臺(tái)式機(jī)3通道BGR,移動(dòng)設(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對(duì)象或人臉檢測(cè)器
CascadeClassifier faceDetector;
std::string faceCascadeFilename = “haarcascade_frontalface_default.xml”;
//友好錯(cuò)誤信息提示
try{
faceDetector.load(faceCascadeFilename);
}
catch (cv::Exception e){}
if (faceDetector.empty())
{
std::cerr 《《 “臉部檢測(cè)器不能加載 (”;
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);
//人臉檢測(cè)只試用于灰度圖像
Mat gray;
Pic2Gray(camerFrame, gray);
//直方圖均勻化(改善圖像的對(duì)比度和亮度)
Mat equalizedImg;
equalizeHist(gray, equalizedImg);
//人臉檢測(cè)用Cascade Classifier::detectMultiScale來進(jìn)行人臉檢測(cè)
int flags = CASCADE_FIND_BIGGEST_OBJECT|CASCADE_DO_ROUGH_SEARCH; //只檢測(cè)臉最大的人
//int flags = CASCADE_SCALE_IMAGE; //檢測(cè)多個(gè)人
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;
}
評(píng)論
查看更多