Opencv与dlib联合进行人脸关键点检测与识别

前言

依赖库: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、FisherFacemodel->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 1imshow("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图片:
这里写图片描述

转载于:https://www.cnblogs.com/mtcnn/p/9412040.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457555.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Category 的一些事

来源&#xff1a;伯乐在线 - Tsui YuenHong 链接&#xff1a;http://ios.jobbole.com/90422/ 点击 → 申请加入伯乐在线专栏作者 新增实践部分&#xff1a;偏方 Hook 进某些方法来添加功能 Category – 简介 Category&#xff08;类别&#xff09;是 Objective-C 2.0 添加的新特…

python tfidf特征变换_机器学习的“万能模板” - 数据分析

最后是文本变量。很遗憾Titanic数据集中没有合适的文本变量。一般我们处理文本变量的方法是&#xff0c;合并所有的文本形成一个变量&#xff0c;然后调用Count Vectorizer或者TfidfVectorizer算法&#xff0c;将文本数据转换成数字。大部分情况下&#xff0c;TfidfVectorizer比…

python实现哈希表

# python 实现哈希表class HashTable:"""哈希函数的构造解决冲突"""def __init__(self, source):self.source sourceself._index []self._val []self.table []self._mod 13def Output(self):print(self._index)print(self._val)def _create…

商品综合评价排名

店内有很多产品&#xff0c;而且包含但不局限于以下指标&#xff1a;浏览量、访客数、平均停留时长、详情页跳出率、下单转化率、下单支付转化率、支付转化率、下单金额、下单商品件数、下单买家数、支付金额、支付商品件数、加购件数、访客平均价值、收藏人数、客单价、搜索支…

ionic资源网站

http://ionichina.com/topic/570b1f4ecd63e4247a7cfcf3 http://doc.ionicmaterialdesign.com/#intro http://ionicmaterial.com/demo/ 10大materialhttp://www.open-open.com/news/view/192f93e转载于:https://www.cnblogs.com/znsongshu/p/6079357.html

pytorch神经网络因素预测_实战:使用PyTorch构建神经网络进行房价预测

微信公号&#xff1a;ilulaoshi / 个人网站&#xff1a;lulaoshi.info本文将学习一下如何使用PyTorch创建一个前馈神经网络(或者叫做多层感知机&#xff0c;Multiple-Layer Perceptron&#xff0c;MLP)&#xff0c;文中会使用PyTorch提供的自动求导功能&#xff0c;训练一个神经…

SQL基本操作

SQL 操作 检索数据 SELECT 检索数据 -- 检索单个列 SELECT 列名 FROM table_name;-- 检索多个列 SELECT 列1, 列2 FROM table_name;-- 检索所有列 SELECT * FROM table_name;-- 检索不同的值 SELECT DISTINCT 列名 FROM table_name;限制检索结果 -- SQL Server / Access SE…

git 忽略 部分文件夹_git提交忽略某些文件或文件夹

记得第一次用 github 提交代码&#xff0c;node_modules 目录死活传不上去&#xff0c;哈哈哈&#xff0c;后来才知道在 .gitignore 文件里设置了忽略 node_modules 目录上传。是的&#xff0c; .gitignore 文件就是设置那些你不想用 git 一起上传的文件和文件夹。比如刚接触到…

Ajax实现原理详解

Ajax&#xff1a;Asynchronous javascript and xml&#xff0c;实现了客户端与服务器进行数据交流过程。使用技术的好处是&#xff1a;不用页面刷新&#xff0c;并且在等待页面传输数据的同时可以进行其他操作。 这就是异步调用的很好体现。首先得了解什么是异步和同步的概念。…

SpringJDBC解析3-回调函数(update为例)

PreparedStatementCallback作为一个接口&#xff0c;其中只有一个函数doInPrepatedStatement&#xff0c;这个函数是用于调用通用方法execute的时候无法处理的一些个性化处理方法&#xff0c;在update中的函数实现&#xff1a; protected int update(final PreparedStatementCr…

python上下文管理器

DAY 23. python上下文管理器 Python 的 with 语句支持通过上下文管理器所定义的运行时上下文这一概念。 此对象的实现使用了一对专门方法&#xff0c;允许用户自定义类来定义运行时上下文&#xff0c;在语句体被执行前进入该上下文&#xff0c;并在语句执行完毕时退出该上下文&…

勾股定理python思路_趣叮咚编程数学揭秘:为什么勾股定理a+b=c?

我们都知道&#xff1a;三角形3个外角之和360度可是谁知道为什么等于360度呢&#xff1f;其实利用编程制作动图演绎了解啦&#xff1a;那勾股定理abc又是为什么呢&#xff1f;还有很多有趣的数学公式都可以演绎&#xff1a;圆的面积公式、圆周长...通过动图演绎原来晦涩难懂的定…

System.InvalidOperationException : 不应有 Response xmlns=''。

xml如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <Response version"2"><datacash_reference>4700203048783633</datacash_reference><information>Failed to identify the card scheme of the supp…

Navicat Premium连接SQL Server

Navicat Premium连接SQL Server 步骤&#xff1a; 激活SQL Server 服务配置SQL Server网络配置连接SQL Server 激活SQLServer服务 直接搜索 计算机管理 点 服务和应用程序&#xff0c; 点 SQL Server配置管理器&#xff0c; 双击第一个SQL Server服务 不出意外的话&#xf…

mysql 单标递归_MySql8 WITH RECURSIVE递归查询父子集的方法

背景开发过程中遇到类似评论的功能是&#xff0c;需要时用查询所有评论的子集。不同数据库中实现方式也不同&#xff0c;本文使用Mysql数据库&#xff0c;版本为8.0Oracle数据库中可使用START [Param] CONNECT BY PRIORMysql 中需要使用 WITH RECURSIVE需求找到name为张三的孩子…

processon完全装逼指南

一、引言 作为一名IT从业者&#xff0c;不仅要有扎实的知识储备&#xff0c;出色的业务能力&#xff0c;还需要具备一定的软实力。软实力体现在具体事务的处理能力&#xff0c;包括沟通&#xff0c;协作&#xff0c;团队领导&#xff0c;问题的解决方案等&#xff0c;这些能力在…

mysql在空闲8小时之后会断开连接(默认情况)

调试程序的过程发现&#xff0c;在mysql连接空闲一定时间&#xff08;默认8小时&#xff09;之后会断开连接&#xff0c;需要重新连接&#xff0c;也引发我对重连机制的思考。转载于:https://www.cnblogs.com/ppzbty/p/5707576.html

selector多路复用_多路复用器Selector

Unix系统有五种IO模型分别是阻塞IO(blocking IO)&#xff0c;非阻塞IO( non-blocking IO)&#xff0c;IO多路复用(IO multiplexing)&#xff0c;信号驱动(SIGIO/Signal IO)和异步IO(Asynchronous IO)。而IO多路复用通常有select&#xff0c;poll&#xff0c;epoll&#xff0c;k…

解决svn log显示no author,no date的方法之一

只要把svnserve.conf中的anon-access read 的read 改为none&#xff0c;也不需要重启svnserve就行 sh-4.1# grep "none" /var/www/html/svn/pro/conf/svnserve.conf ### and "none". The sample settings below are the defaults. anon-access none转载…

REST framework 权限管理源码分析

REST framework 权限管理源码分析 同认证一样&#xff0c;dispatch()作为入口&#xff0c;从self.initial(request, *args, **kwargs)进入initial() def initial(self, request, *args, **kwargs):# .......# 用户认证self.perform_authentication(request)# 权限控制self.che…