2019-05-14 15:08:11 2572浏览
在现如今生活中,时时刻刻都在使用智能机器,今天千锋扣丁学堂Python培训老师给大家介绍一下关于Dlib+OpenCV深度学习人脸识别的方法示例,文中通过示例代码介绍的非常详细,下面我们一起来看一下吧。在这个系统中我预先存储了下面几位明星的正面头像的128D人脸特征,当然你可以存储和导入更多的人脸。然后经过人脸检测、人脸图像处理,和人脸识别等步骤识别出相应的人脸信息,识别效果如下(怕大家被丑到所以用了明星的图片,没有用真实的人脸–没有做活体检测):
int FACE_RECOGNITION::load_db_faces(void)
{
intrc = -1;
longhFile = 0;
struct_finddata_tfileinfo;
frontal_face_detectordetector =get_frontal_face_detector();
// We will also use a face landmarking model to align faces to a standard pose: (see face_landmark_detection_excpp for an introduction)
deserialize("shape_predictor_68_face_landmarksdat") >>sp;
// And finally we load the DNN responsible for face recognition
deserialize("dlib_face_recognition_resnet_model_vdat") >>net;
if ((hFile =_findfirst("\\faces\\*jpg", &fileinfo)) != -1)
{
do
{
if ((fileinfoattrib &_A_ARCH))
{
if (strcmp(fileinfoname,"") != 0 && strcmp(fileinfoname,"") != 0)
{
if (!strcmp(strstr(fileinfoname,"") + 1 , "jpg"))
{
cout <<"This file is an image file!" <<fileinfoname <<endl;
matrix<rgb_pixel>img;
charpath[260];
sprintf_s(path,"\\faces\\%s",fileinfoname);
load_image(img,path);
image_windowwin(img);
for (autoface :detector(img))
{
autoshape =sp(img,face);
matrix<rgb_pixel>face_chip;
extract_image_chip(img,get_face_chip_details(shape, 150, 25),face_chip);
//Record the all this face's information
FACE_DESCsigle_face;
sigle_faceface_chip =face_chip;
sigle_facename =fileinfoname;
std::vector<matrix<rgb_pixel>>face_chip_vec;
std::vector<matrix<float, 0, 1>>face_all;
face_chip_vecpush_back(move(face_chip));
//Asks the DNN to convert each face image in faces into a 128D vector
face_all =net(face_chip_vec);
//Get the feature of this person
std::vector<matrix<float, 0, 1>>::iteratoriter_begin = face_allbegin(),
iter_end =face_allend();
if (face_allsize() > 1)break;
sigle_faceface_feature = *iter_begin;
//all the person description into vector
face_desc_vecpush_back(sigle_face);
winadd_overlay(face);
}
}
else
{
cout <<"This file is not image file!" <<fileinfoname <<endl;
}
}
}
else
{
//filespush_back(passign(path)append("\\")append(fileinfoname));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
returnrc;
}
intcapture_face(Matframe,Mat&out)
{
Matgray;
Matface;
intrc = -1;
if (frame.empty() || !frame.data)return -1;
cvtColor(frame,gray,CV_BGR2GRAY);
int *pResults =NULL;
unsignedchar *pBuffer = (unsignedchar *)malloc(DETECT_BUFFER_SIZE);
if (!pBuffer)
{
fprintf(stderr,"Can not alloc buffer.\n");
return -1;
}
//pResults = facedetect_frontal_tmp((unsigned char*)(gray.ptr(0)), gray.cols, gray.rows, gray.step,
// 1.2f, 5, 24);
pResults =facedetect_multiview_reinforce(pBuffer, (unsignedchar*)(gray.ptr(0)),gray.cols,gray.rows, (int)gray.step,
1.2f, 2, 48, 0, 1);
//printf("%d faces detected.\n", (pResults ? *pResults : 0));//重复运行
//print the detection results
if (pResults !=NULL)
{
for (inti = 0;i < (pResults ? *pResults : 0);i++)
{
short *p = ((short*)(pResults + 1)) + 6 *i;
intx =p[0];
inty =p[1];
intw =p[2];
inth =p[3];
intneighbors =p[4];
Rect_<float>face_rect =Rect_<float>(x,y,w, h);
face =frame(face_rect);
printf("face_rect=[%d, %d, %d, %d], neighbors=%d\n",x,y, w,h,neighbors);
Pointleft(x,y);
Pointright(x +w,y + h);
cv::rectangle(frame,left,right, Scalar(230, 255, 0), 4);
}
//imshow("frame", frame);
if (face.empty() || !face.data)
{
face_detect_count = 0;
return -1;
}
if (face_detect_count++ > 30)
{
imshow("face",face);
out =face.clone();
return 0;
}
}
else
{
//face is moving, and reset the detect count
face_detect_count = 0;
}
returnrc;
}
matrix<rgb_pixel> face_cap;
//save the capture in the project directory
load_image(face_cap, ".\\cap.jpg");
//Display the raw image on the screen
image_window win1(face_cap);
frontal_face_detector detector = get_frontal_face_detector();
std::vector<matrix<rgb_pixel>> vect_faces;
for (auto face : detector(face_cap))
{
auto shape = face_recognize.sp(face_cap, face);
matrix<rgb_pixel> face_chip;
extract_image_chip(face_cap, get_face_chip_details(shape, 150, 0.25), face_chip);
vect_faces.push_back(move(face_chip));
win1.add_overlay(face);
}
if (vect_faces.size() != 1)
{
cout <<"Capture face error! face number "<< vect_faces.size() << endl;
cap.release();
goto CAPTURE;
}
//Use DNN and get the capture face's feature with 128D vector
std::vector<matrix<float, 0, 1>> face_cap_desc = face_recognize.net(vect_faces);
//Browse the face feature from the database, and find the match one
std::pair<double,std::string> candidate_face;
std::vector<double> len_vec;
std::vector<std::pair<double, std::string>> candi_face_vec;
candi_face_vec.reserve(256);
for (size_t i = 0; i < face_recognize.face_desc_vec.size(); ++i)
{
auto len = length(face_cap_desc[0] - face_recognize.face_desc_vec[i].face_feature);
if (len < 0.45)
{
len_vec.push_back(len);
candidate_face.first = len;
candidate_face.second = face_recognize.face_desc_vec[i].name.c_str();
candi_face_vec.push_back(candidate_face);
#ifdef _FACE_RECOGNIZE_DEBUG
char buffer[256] = {0};
sprintf_s(buffer, "Candidate face %s Euclid length %f",
face_recognize.face_desc_vec[i].name.c_str(),
len);
MessageBox(CString(buffer), NULL, MB_YESNO);
#endif
}
else
{
cout << "This face from database is not match the capture face, continue!" << endl;
}
}
//Find the most similar face
if (len_vec.size() != 0)
{
shellSort(len_vec);
int i(0);
for (i = 0; i != len_vec.size(); i++)
{
if (len_vec[0] == candi_face_vec[i].first)
break;
}
char buffer[256] = { 0 };
sprintf_s(buffer, "The face is %s -- Euclid length %f",
candi_face_vec[i].second.c_str(), candi_face_vec[i].first);
if (MessageBox(CString(buffer), NULL, MB_YESNO) == IDNO)
{
face_record();
}
}
else
{
if (MessageBox(CString("Not the similar face been found"), NULL, MB_YESNO) == IDYES)
{
face_record();
}
}
face_detect_count = 0;
frame.release();
face.release();
当人脸或是物体快速的在摄像头前活动时,会导致系统异常抛出,异常提示如下:
Mat frame;
Mat face;
VideoCapture cap(0);
if (!cap.isOpened()) {
AfxMessageBox(_T("Please check your USB camera's interface num."));
}
try
{
while (1)
{
check_close(cap);
cap >> frame;
if (!frame.empty())
{
if (capture_face(frame, face) == 0)
{
//convert to IplImage format and then save with .jpg format
IplImage face_Img;
face_Img = IplImage(face);
//save the capture face to the project directory
cvSaveImage("./cap.jpg", &face_Img);
break;
}
imshow("view", frame);
}
int c = waitKey(10);
if ((char)c == 'c') { break; }
}
}
catch (exception& e)
{
cout << "\nexception thrown!" << endl;
cout << e.what() << endl;
#ifdef _CAPTURE_DEBUG
MessageBox(CString(e.what()), NULL, MB_YESNO);
#endif
goto CAPTURE;
}
在catch中将捕获到的异常信息打印出来:
【关注微信公众号获取更多学习资料】 【扫码进入Python全栈开发免费公开课】