此应用程序可用于检测视频中检测到人脸的特征点。此应用程序会首先在当前视频帧中检测人脸,然后找到对应的人脸特征点。您只需输入视频即可。
要运行此示例,需键入以下命令:
./sampleDetectLandmarks -file=trained_model.dat -face_cascade=lbpcascadefrontalface.xml -video=/path_to_video/video.avi
命令参数说明
* model_filename f : (必需)用于存储要加载的已训练模型的二进制文件路径 [示例 - /data/file.dat]
- video v : (必需)要检测人脸特征点的视频路径。[示例 - /data/video.avi]
- face_cascade c : (必需)要用作人脸检测器的 face cascade xml 文件路径。
理解代码
本教程将讲解人脸特征识别示例代码。直接跳转到代码
c++
CascadeClassifier face_cascade;
bool myDetector( InputArray image, OutputArray ROIs );
bool myDetector( InputArray image, OutputArray ROIs ){
Mat gray;
std::vector<Rect> faces;
if(image.channels()>1){
cvtColor(image.getMat(),gray,COLOR_BGR2GRAY);
}
else{
gray = image.getMat().clone();
}
equalizeHist( gray, gray );
face_cascade.detectMultiScale( gray, faces, 1.1, 3,0, Size(30, 30) );
Mat(faces).copyTo(ROIs);
return true;
}
人脸特征 API 向用户提供功能,可使用他们自己的人脸检测器用于人脸特征识别。以上代码创建了一个人脸检测器示例。以上函数将作为函数指针传递到人脸特征 API 中。
c++
VideoCapture cap(video);
if(!cap.isOpened()){
cerr<<"无法加载视频。请提供正确的路径"<<endl;
return -1;
}
以上代码创建一个视频捕获对象,然后加载视频。如果视频未正确加载,则会提示用户,否则代码将继续运行。
c++
Mat img = imread(image);
face_cascade.load(cascade_name);
FacemarkKazemi::Params params;
params.configfile = configfile_name;
Ptr<Facemark> facemark = FacemarkKazemi::create(params);
facemark->setFaceDetector(myDetector);
以上代码创建一个人脸特征检测类的指针。以上创建的人脸检测器必须作为函数指针传递到为检测人脸创建的人脸特征指针。
c++
vector<Rect> faces;
vector< vector<Point2f> > shapes;
Mat img;
上面的代码创建了一个向量,用于存储检测到的人脸,还创建了一个向量,用于存储当前帧中每个检测到的人脸的形状。
c++
while(1){
faces.clear();
shapes.clear();
cap>>img;
resize(img,img,Size(600,600),0,0,INTER_LINEAR_EXACT);
facemark->getFaces(img,faces);
if(faces.size()==0){
cout<<"No faces found in this frame"<<endl;
}
else{
for( size_t i = 0; i < faces.size(); i++ )
{
cv::rectangle(img,faces[i],Scalar( 255, 0, 0 ));
}
if(facemark->fit(img,faces,shapes))
{
for(unsigned long i=0;i<faces.size();i++){
for(unsigned long k=0;k<shapes[i].size();k++)
cv::circle(img,shapes[i][k],3,cv::Scalar(0,0,255),FILLED);
}
}
}
namedWindow("Detected_shape");
imshow("Detected_shape",img);
if(waitKey(1) >= 0) break;
}
上面的代码将读取每一帧,并针对每个形状检测人脸和地标。然后它将显示当前帧。
运行上面的代码后,你将获得类似以下的结果:
示例视频