码迷,mamicode.com
首页 > 其他好文 > 详细

人脸识别之一图像采集及人脸库的建立

时间:2019-06-05 19:34:17      阅读:677      评论:0      收藏:0      [点我收藏+]

标签:copy   check   size_t   data   obj   作者   pat   please   一个人   

人脸识别之第一步,人脸库的建立。

 

在官方文档中,提供一个人脸库的下载,可以下载回来看看人家的是什么格式的。

我们选择AT&T人脸库下载的下载:http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html

AT&T Facedatabase又称ORL人脸数据库,40个人,每人10张照片。照片在不同时间、不同光照、不同表情(睁眼闭眼、笑或者不笑)、不同人脸细节(戴眼镜或者不戴眼镜)下采集。所有的图像都在一个黑暗均匀的背景下采集的,正面竖直人脸(有些有有轻微旋转)。

下载回来的是压缩包,先解压得到orl_faces文件夹,文件夹下有40个文件夹,命名从“s1”~"s40",每个文件夹放的是同一人的照片,里面有10张人脸照。

但都是 .pgm 格式的 92 x 112 图片,在windows下打不开,可在linux下打开,如下:

 

 

看一遍官方提供的人脸库,大概知道如何存放、处理图片。后面参考官方方法建立自己的图片即可。

废话少说,马上行动。

 

一、实现步骤与方法

思路很清晰,如下:

1、打开摄像头,采集图像;

 

2、加载人脸分类器;

 

3、人脸检测,并框出人脸部分并显示图像;

 

4、在检测到人脸条件下,一键拍照;

 

5、对人脸部分,调整大小并写成指定目录下的图像文件;

 

二、实现代码

你可自己写代码实现这功能,亦可直接COPY代码来用,这只是辅助功能而已。

代码如下:

#include "opencv2/objdetect.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
#include <stdio.h>

using namespace cv;
using namespace std;

int resize_save(Mat& faceIn, char *path, int FaceSeq);
int get_face(char *path);

int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("usage: %s <path>\n", argv[0]);
return -1;
}

get_face(argv[1]);

return 0;
}

int get_face(char *path)
{
CascadeClassifier face_cascade;
VideoCapture camera;
char key = 0;
Mat frame;
int ret = 0;
int faceNum = 1;
vector<Rect> faces;
Mat img_gray;
Mat faceImg;

camera.open(0); // 打开摄像头
if(!camera.isOpened())
{
cout << "open camera failed. " << endl;
return -1;
}
cout << "open camera succeed. " << endl;

// 加载人脸分类器
ret = face_cascade.load("/root/library/opencv/opencv-3.2.0/data/haarcascades/haarcascade_frontalface_alt2.xml");
if( !ret )
{
printf("load xml failed.\n");
return -1;
}
cout << "load xml succeed. " << endl;

while (1)
{
camera >> frame;
if(frame.empty())
{
continue;
}

cvtColor(frame, img_gray, COLOR_BGR2GRAY);
equalizeHist(img_gray, img_gray);

// 检测目标
face_cascade.detectMultiScale(img_gray, faces, 1.1, 3, 0, Size(50, 50));

for(size_t i =0; i<faces.size(); i++)
{
/* 画矩形框出目标 */
rectangle(frame, Point(faces[0].x, faces[0].y), Point(faces[0].x + faces[0].width, faces[0].y + faces[0].height),
Scalar(0, 255, 0), 1, 8);
}
imshow("camera", frame); // 显示
key = waitKey(1); // 显示后要添加延时

switch (key)
{
case ‘p‘: // 按 P 一键拍脸
// 只限定检测一个人脸
if(faces.size() == 1)
{
faceImg = frame(faces[0]);
ret = resize_save(faceImg, path, faceNum); // 调整大小及保存
if(ret == 0)
{
printf("resize_save success.\n");
faceNum ++;
}
}
break;

case 27: // 按 Esc 键退出
cout << "Esc..." << endl;
return 0;

default:
break;
}
}
}

int resize_save(Mat& faceIn, char *path, int FaceSeq)
{
string strName;
Mat image;
Mat faceOut;
int ret;

if(faceIn.empty())
{
printf("faceIn is empty.\n");
return -1;
}

if (faceIn.cols > 100)
{
resize(faceIn, faceOut, Size(92, 112)); // 调整大小,这里选择与官方人脸库图片大小兼容
strName = format("%s/%d.jpg", path, FaceSeq); // 先要创建文件夹
ret = imwrite(strName, faceOut); // 文件名后缀要正确 .jpg .bmp ...
if(ret == false) // 出现错误,请检测文件名后缀、文件路径是否存在
{
printf("imwrite failed!\n");
printf("please check filename[%s] is legal ?!\n", strName.c_str());
return -1;
}
imshow(strName, faceOut);
}
waitKey(20);

return 0;
}

操作说明:

编译成功后,执行可执行文件须提供参数,该参数为存放人脸图像的目录,且须为已有目录。

按“P”键一键拍照取脸保存,按“Esc”键退出。

若执行 imwrite() 函数失败时,请检查参数目录是否存在,要保存的文件名后缀是否合法。

此程序保存为 .jpg 格式,命名采用编号法由1递增。


---------------------
作者:曾哥哥_zeng
来源:CSDN
原文:https://blog.csdn.net/qq_30155503/article/details/79776485

人脸识别之一图像采集及人脸库的建立

标签:copy   check   size_t   data   obj   作者   pat   please   一个人   

原文地址:https://www.cnblogs.com/lx17746071609/p/10981141.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!