前言

依赖库:opencv 2.4.9 /dlib 19.0/libfacedetection

本篇不记录如何配置,重点在实现上。使用libfacedetection实现人脸区域检测,联合dlib标记人脸特征点,最后使用opencv的FaceRecognizer实现人脸识别。

准备工作

1、配置好Opencv2.4.9。(Opencv3.1需要另外下载一个包才有FaceRecognizer)

2、配置好dlib 19.0(版本其实没有多大关系)

3、配置好ShiQi.Yu的人脸检测库

思想

训练模块:人脸检测——>获取人脸区域的点坐标——>人脸关键点标记——>人脸对正——>归一化处理——>保存图片——>手动筛选图片——>训练样本——>得到train.xml

识别模块:读取train.xml——>循环(人脸检测——>获取人脸区域的点坐标——>人脸关键点标记——>人脸对正——>归一化处理——>送入model->predict——>预测出结果——>putText在方框上写出名字)

结果

识别速度:0.15~0.25秒,Release平台。

识别精度:还可以

使用了一段中国好声音的视频做识别。







当然,这里用的是Fisherface算法,主要还是样本不多,已经可以搞定了。

代码

ReadCSV.h

#include <opencv.hpp>
#include <iostream>
#include <fstream>
using namespace cv;
using namespace std;
static void read_csv(const string& filename, cv::vector<Mat>& images, cv::vector<int>& labels, char separator = ';') {
std::ifstream file(filename.c_str(), ifstream::in);
if (!file) {
string error_message = "No valid input file was given, please check the given filename.";
CV_Error(CV_StsBadArg, error_message);
}
string line, path, classlabel;
while (getline(file, line)) {
stringstream liness(line);
getline(liness, path, separator);
getline(liness, classlabel);
if (!path.empty() && !classlabel.empty()) {
images.push_back(imread(path, 0));
labels.push_back(atoi(classlabel.c_str()));
}
}
}

FaceRotate.h

#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>
#include <dlib/image_io.h>
#include<dlib/opencv/cv_image.h>
#include <dlib/opencv.h> using namespace dlib; frontal_face_detector detector = get_frontal_face_detector();
shape_predictor sp;//Already get

FaceRecognition.cpp

#include <FaceDetect.h>
#include <ReadCSV.h>
const int namenumber = 4;//测试的人脸数量
const string textname[namenumber] = { "Hariem", "Miss.Na", "Mr.Wang", "Jay.Chou" };//做一个储存人脸名字的数组 Ptr<FaceRecognizer> GetTrainModel(string fn_csv)//输入CSV文件的路径名
{
vector<Mat> images;
vector<int> labels;
try {
read_csv(fn_csv, images, labels);
}
catch (cv::Exception& e) {
cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
// 文件有问题,我们啥也做不了了,退出了
exit(1);
}
// 如果没有读取到足够图片,我们也得退出.
if (images.size() <= 1) {
string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";
CV_Error(CV_StsError, error_message);
}
Ptr<FaceRecognizer> model = createEigenFaceRecognizer(80);//创建人脸识别类 可修改 LBPHFace、EigenFace、FisherFace
model->train(images, labels);
return model;
} int main()
{
Dlib_Predefine();//加载dlib的文件
Ptr<FaceRecognizer> model = GetTrainModel("face.csv");//获得模型
VideoCapture cap("好声音.mp4");
Mat frame,gray;
while (true)
{
cap >> frame;
if (!frame.empty())
{
gray = FaceDetect(frame);
if (!gray.empty())
putText(frame, textname[model->predict(gray)], Point(50, 50), FONT_HERSHEY_DUPLEX, 3, Scalar(230, 255, 0), 2);//model->predict(frame) = predictLabel 名字写在 1 1
imshow("Face Recogniton", frame);
waitKey(1);
}
else{ cout << "The Video's end." <<endl; break; }
} }

FaceDetect.cpp

用了掩码。

#include <FaceDetect.h>
#include <FaceRotate.h>
void Dlib_Predefine()
{
deserialize("shape_predictor_68_face_landmarks.dat") >> sp;//读入标记点文件
} cv::Mat FaceToOne(cv::Mat source)//归一化处理函数
{ cv::equalizeHist(source, source);//直方图均衡
cv::resize(source, source, cv::Size(92, 112));//裁剪
cv::Mat Mask = cv::imread("mask.jpg", 0);
cv::Mat changedMask;
source.copyTo(changedMask, Mask);
return changedMask;
} Mat FaceDetect(Mat frame)//脸是否存在
{
Mat gray, error;
cvtColor(frame, gray, CV_BGR2GRAY);
int * pResults = NULL;
pResults = facedetect_frontal_tmp((unsigned char*)(gray.ptr(0)), gray.cols, gray.rows, gray.step, 1.2f, 5, 24);
int peopleNUM = (pResults ? *pResults : 0); for (int i = 0; i < peopleNUM; i++)//代表有几张人脸(pResults ? *pResults : 0)
{
short * p = ((short*)(pResults + 1)) + 6 * i;
Rect opencvRect(p[0], p[1], p[2], p[3]);
//gray = gray(opencvRect);
cv::rectangle(frame, opencvRect, Scalar(230, 255, 0));
dlib::rectangle dlibRect((long)opencvRect.tl().x, (long)opencvRect.tl().y, (long)opencvRect.br().x - 1, (long)opencvRect.br().y - 1);
//人脸对齐技术提高了准确率
dlib::full_object_detection shape = sp(dlib::cv_image<uchar>(gray), dlibRect);//标记点
std::vector<full_object_detection> shapes;
shapes.push_back(shape);//把点保存在了shape中
dlib::array<array2d<rgb_pixel>> face_chips;
extract_image_chips(dlib::cv_image<uchar>(gray), get_face_chip_details(shapes), face_chips);
Mat pic = toMat(face_chips[0]);
cvtColor(pic, pic, CV_BGR2GRAY);
return FaceToOne(pic);
}
return error;
}

FaceDetect.h

#include <opencv.hpp>
#include "facedetect-dll.h" using namespace cv;
using namespace std; Mat FaceDetect(Mat frame);
void Dlib_Predefine();//dlib 预定义的函数

FaceRotate.h

#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>
#include <dlib/image_io.h>
#include<dlib/opencv/cv_image.h>
#include <dlib/opencv.h> using namespace dlib; frontal_face_detector detector = get_frontal_face_detector();
shape_predictor sp;//Already get

Mask图片:

Opencv与dlib联合进行人脸关键点检测与识别的更多相关文章

  1. OpenCV实战:人脸关键点检测(FaceMark)

    Summary:利用OpenCV中的LBF算法进行人脸关键点检测(Facial Landmark Detection) Author:    Amusi Date:       2018-03-20 ...

  2. dlib人脸关键点检测的模型分析与压缩

    本文系原创,转载请注明出处~ 小喵的博客:https://www.miaoerduo.com 博客原文(排版更精美):https://www.miaoerduo.com/c/dlib人脸关键点检测的模 ...

  3. OpenCV Facial Landmark Detection 人脸关键点检测

    Opencv-Facial-Landmark-Detection 利用OpenCV中的LBF算法进行人脸关键点检测(Facial Landmark Detection) Note: OpenCV3.4 ...

  4. 机器学习进阶-人脸关键点检测 1.dlib.get_frontal_face_detector(构建人脸框位置检测器) 2.dlib.shape_predictor(绘制人脸关键点检测器) 3.cv2.convexHull(获得凸包位置信息)

    1.dlib.get_frontal_face_detector()  # 获得人脸框位置的检测器, detector(gray, 1) gray表示灰度图, 2.dlib.shape_predict ...

  5. 用keras实现人脸关键点检测(2)

    上一个代码只能实现小数据的读取与训练,在大数据训练的情况下.会造内存紧张,于是我根据keras的官方文档,对上一个代码进行了改进. 用keras实现人脸关键点检测 数据集:https://pan.ba ...

  6. keras实现简单CNN人脸关键点检测

    用keras实现人脸关键点检测 改良版:http://www.cnblogs.com/ansang/p/8583122.html 第一步:准备好需要的库 tensorflow  1.4.0 h5py ...

  7. Python 3 利用 Dlib 和 sklearn 人脸笑脸检测机器学习建模

    0. 引言 利用机器学习的方法训练微笑检测模型,输入一张人脸照片,判断是否微笑: 精度在 95% 左右( 使用的数据集中 69 张没笑脸,65 张有笑脸 ): 图1 测试图像与检测结果 项目实现的笑脸 ...

  8. opencv+python+dlib人脸关键点检测、实时检测

    安装的是anaconde3.python3.7.3,3.7环境安装dlib太麻烦, 在anaconde3中新建环境python3.6.8, 在3.6环境下安装dlib-19.6.1-cp36-cp36 ...

  9. 人脸识别之Python DLib库进行人脸关键点识别

    一.首先安装DLib模块 这里只介绍linux安装的过程,windows安装过程请自行百度 1.首先,安装dlib.skimage前:先安装libboost sudo apt-get install ...

随机推荐

  1. [转]JVM 堆内存设置原理

    堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...

  2. (44)C#网络2

    一.用SmtpClient类发送邮件 允许应用程序使用简单邮件传输协议 (SMTP) 发送电子邮件 using System.Net.Mail; SmtpClient smtpClient = new ...

  3. collection包1.1.0都升级了什么功能

    collection包1.1.0都升级了什么功能 jianfengye/collection(https://github.com/jianfengye/collection) 这个包喜迎第一个子版本 ...

  4. T1013 求先序排列 codevs

    http://codevs.cn/problem/1013/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Descr ...

  5. luogu P2296 寻找道路

    题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...

  6. Annotation基本概念,作用以及举例说明。

    Annotation即注解,是Jav5新特征,Annotatio提供一些本来不属于程序的数据,用来将任何的信息或元数据(metadata)与程序元素(类.方法.成员变量等)进行关联.为程序的元素(类. ...

  7. NOIP前必须记住的30句话

    NOIP前必须记住的30句话 1.比赛前一天晚上请准备好你的各种证件,事先查好去往考场的路线2.比赛之前请先调整你的屏幕分辨率到你喜欢的大小3.比赛之前请把编译器的字体调为你平时惯用的字体,尤其是注意 ...

  8. Android自己主动升级框架

    先看效果 使用 package com.ydl.versionupdate; import android.app.Activity; import android.content.Context; ...

  9. Java学习之集合

    1.ArrayList:采用数组的形式保存对象,这种方式将对象保存在连续的位置中,所以查询效率比较高,但是插入删除时麻烦,并且ArrayList不是线程安全的. 2.Vector:保存对象的方式与Ar ...

  10. Erlang进程堆垃圾回收机制

    原文:Erlang进程堆垃圾回收机制 作者:http://blog.csdn.net/mycwq 每一个Erlang进程创建之后都会有自己的PCB,栈,私有堆.erlang不知道他创建的进程会用到哪种 ...