QT+Opencv实现人脸检测与性别识别(1)
2017-08-17 21:52
1021 查看
seetaface开源人脸检测框架实现人脸检测,opencv+dnn模块实现性别分类,qt做显示界面,完成一个课程设计。
依赖库:opencv3.1+ 包含dnn模块,QT5
我们用seetaface开源人脸检测做人脸检测,检测出的人脸区域为红色框部分。为了让输入到卷积网络的图片包含充分的信息,我们把人脸区域按照一定方法,扩展到一个更合理的区域,即绿色框区域。实际的训练集与验证集都应该是最右边的图片,即截取之后的图片。
实现步骤
1.用Python脚本获取图片文件访问路径
形如
E:\female\Adelina_Avila_0001.jpg;0
E:\female\Adelina_Avila_0001.jpg;1
这样的txt文件,前面是文件绝对路径,后面是标签,0表示女性。
2.用seetaface人脸检测提取绿色框部分并保存
遍历之前Python脚本获取的图片访问路径,逐个检测人脸,人脸区域扩展,依据label 0 1保存到femaleroi和maleroi文件夹
上述Python与cpp代码完成了将检测到的人脸扩展到一定范围,并将此范围截取保存到对应文件夹的操作。训练集和验证集可以自己切分,最后会有MaleTrainRoi, FemaleTrainRoi, MaleValRoi, FemaleValRoi四个文件夹,为后续使用caffe训练自己的数据做准备。
依赖库:opencv3.1+ 包含dnn模块,QT5
1.性别分类网络训练
1.1.训练数据准备
下载lfw人脸数据库,由于原始数据集未提供性别标签,参考了GitHub项目LFWgender,访问一个网络api接口,根据姓名对数据添加上标签。最终获得了约1600张图片作为训练数据,600张图片作为验证集,男女样本各一半。1.2.人脸检测与脸部区域截取
性别识别的第一步是人脸检测,而我们送到卷积网络训练和预测的数据,实际上就是检测出来的人脸区域,因此,我们首先要对lfw数据集做人脸检测与脸部截取,截取前与截取后的图如下我们用seetaface开源人脸检测做人脸检测,检测出的人脸区域为红色框部分。为了让输入到卷积网络的图片包含充分的信息,我们把人脸区域按照一定方法,扩展到一个更合理的区域,即绿色框区域。实际的训练集与验证集都应该是最右边的图片,即截取之后的图片。
实现步骤
1.用Python脚本获取图片文件访问路径
形如
E:\female\Adelina_Avila_0001.jpg;0
E:\female\Adelina_Avila_0001.jpg;1
这样的txt文件,前面是文件绝对路径,后面是标签,0表示女性。
#encoding:utf-8 import os ''' 获取male样本和female样本中的图片的绝对路径, 并保存在txt文件中,male样本路径后加上标签1,female样本路径后加上标签2, 如 male0.jpg;1 male1.jpg;1 female0.jpg;2 female1.jpg;2 ''' #root = os.getcwd() #print root male_path = os.path.abspath('female') #male相对路径 file_list = os.listdir(male_path)#female路径下的图片相对路径 male0.jpg #print file_list f = open('label.txt','w') abs_path_list=[]#图片绝对路径 print 'male......' for file in file_list: file_name = male_path+'\\'+file print file_name abs_path_list.append(file_name+';0\n') female_path = os.path.abspath('valfemale') file_list = os.listdir(female_path) print 'female......' for file in file_list: file_name = female_path+'\\'+file abs_path_list.append(file_name+';1\n') f.writelines(abs_path_list)
2.用seetaface人脸检测提取绿色框部分并保存
遍历之前Python脚本获取的图片访问路径,逐个检测人脸,人脸区域扩展,依据label 0 1保存到femaleroi和maleroi文件夹
#include <cstdint> #include <fstream> #include <iostream> #include <string> #include <opencv2/imgproc.hpp> #include <opencv2/highgui.hpp> //#include<opencv2/opencv.hpp> #include "face_detection.h" using namespace std; using namespace cv; void read_csv(string& fileName, vector<string>& images, vector<int>& labels, char separator = ';')//参考opencv官网的一段例子 { ifstream file(fileName.c_str(), ifstream::in); string line, path, label; while (getline(file, line)) { stringstream lines(line); getline(lines, path, separator); getline(lines, label); if (!path.empty() && !label.empty()) { images.push_back(path); labels.push_back(atoi(label.c_str())); } } } void SplitString(const std::string& s, std::vector<std::string>& v, const std::string& c) //为了从E:/female/Adelina_Avila_0001.jpg截取Adelina_Avila_0001.jpg字符段写的字符串函数 { std::string::size_type pos1, pos2; pos2 = s.find(c); pos1 = 0; while (std::string::npos != pos2) { v.push_back(s.substr(pos1, pos2 - pos1)); pos1 = pos2 + c.size(); pos2 = s.find(c, pos1); } if (pos1 != s.length()) v.push_back(s.substr(pos1)); } int main() { seeta::FaceDetection detector("seeta_fd_frontal_v1.0.bin"); detector.SetMinFaceSize(40); detector.SetScoreThresh(2.f); detector.SetImagePyramidScaleFactor(0.8f); detector.SetWindowStep(4, 4); vector<string> images; vector<int> labels; string csv_path = "E:/label.txt"; read_csv(csv_path, images, labels); for (int i = 0; i < labels.size();++i) { string img_path = images[i]; int label = labels[i]; cv::Mat img = cv::imread(img_path, cv::IMREAD_UNCHANGED); cv::Mat img_gray; if (img.channels() != 1) cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY); else img_gray = img; seeta::ImageData img_data; img_data.data = img_gray.data; img_data.width = img_gray.cols; img_data.height = img_gray.rows; img_data.num_channels = 1; std::vector<seeta::FaceInfo> faces = detector.Detect(img_data); #ifdef USE_OPENMP cout << "OpenMP is used." << endl; #else cout << "OpenMP is not used. " << endl; #endif #ifdef USE_SSE cout << "SSE is used." << endl; #else cout << "SSE is not used." << endl; #endif cv::Rect face_rect; int32_t num_face = static_cast<int32_t>(faces.size()); cout << "人脸个数" << num_face << endl; for (int32_t i = 0; i < num_face; i++) { face_rect.x = faces[i].bbox.x; face_rect.y = faces[i].bbox.y; face_rect.width = faces[i].bbox.width; face_rect.height = faces[i].bbox.height; //扩充脸部至更大范围的头部,250是原图片大小 float extend = MIN(MIN(face_rect.x, face_rect.y), MIN(250 - 1 - face_rect.x - face_rect.width, 250 - 1 - face_rect.y - face_rect.height)); extend = MIN(extend, face_rect.height / 4); face_rect.x -= extend; face_rect.y -= extend; face_rect.width = face_rect.width + 2 * extend; face_rect.height = face_rect.height + 2 * extend; cout << "人脸大小" << face_rect.size() << endl; if ((face_rect.x + face_rect.width)>img.rows || (face_rect.y + face_rect.height) > img.cols ||(face_rect.x<0) ||(face_rect.y<0)) continue; cv::Mat roi; img(face_rect).copyTo(roi); string maleroot = "E:/valmale/"; string femaleroot = "E:/valfemale/"; vector<string> vs; string c = "/"; SplitString(img_path, vs, c);//截取图片文件名,以便存储roi图片 if (label == 0) cv::imwrite(maleroot + vs[vs.size() - 1], roi); //vs vector(E:,female,Adelina_Avila_0001.jpg),所以vs.size()-1指向最后的元素 else cv::imwrite(femaleroot + vs[vs.size() - 1], roi); //cv::rectangle(img, face_rect, CV_RGB(0, 0, 255), 4, 8, 0); } } return 0; }
上述Python与cpp代码完成了将检测到的人脸扩展到一定范围,并将此范围截取保存到对应文件夹的操作。训练集和验证集可以自己切分,最后会有MaleTrainRoi, FemaleTrainRoi, MaleValRoi, FemaleValRoi四个文件夹,为后续使用caffe训练自己的数据做准备。
相关文章推荐
- QT+Opencv实现人脸检测与性别识别(2)
- OpenCV&Qt学习之四——OpenCV 实现人脸检测与相关知识整理
- OpenCV&Qt学习之四——OpenCV 实现人脸检测与相关知识整理
- OpenCV&Qt学习之四——OpenCV 实现人脸检测与相关知识整理
- Linux系统下利用OpenCV实现人脸检测和基于LBPH算法的人脸识别
- Android使用OpenCV实现「人脸检测」和「人脸识别」
- OpenCV&Qt学习之四——OpenCV 实现人脸检测与相关知识整理
- VS2010+Opencv2.4.4+MFC实现人脸检测与识别
- 基于QT和OpenCV的人脸检测识别系统(1)
- 基于QT和OpenCV的人脸检测识别系统(2)
- Qt+Caffe+OpenCV——【一个基于VGG网络的人脸识别考勤系统】(一)人脸检测与识别模块
- 基于QT和OpenCV的人脸检测识别系统(2)
- C++开发人脸性别识别教程(4)——OpenCv的人脸检测函数
- Android使用OpenCV实现「人脸检测」和「人脸识别」
- OpenCV结合V4l2实现人脸检测以及人脸识别
- 代码C++, opencv实现人脸识别,人脸检测,人脸匹配,视频中的人脸检测,摄像头下的人脸检测等
- 人脸识别中的检测(在Opencv中加入了QT)
- openCV java(JFrame) 实现人脸识别,人脸自动检测,自动保存裁剪后人脸
- QT+opencv实现人脸检测并提取裁剪
- Java使用OpenCV实现人脸识别/人眼检测/图片截取/合成/添加水印