OpenCV实践之路——人脸识别之一数据收集和预处理
2017-11-21 21:42
971 查看
参考:http://blog.csdn.net/xingchenbingbuyu/article/details/51386949
人脸检测可以利用opencv自带的分类器,但是人脸识别就需要自己收集数据,自己训练分类器了。opencv给出的有人脸识别的教程:Face Recognition with OpenCV。网上也可以找到中文版本的。
下载下来之后是这样的:
可以看到每个人一个文件夹,每个文件夹下是这个人的十张照片,但是不是我们熟悉的BMP或者是PNG或者是JPEG格式的,而是PGM格式的。windows7自带的照片查看器和画图软件都不能打开这种格式的图片。不过好在我昨天刚对imread()函数研究过:使用imread()函数读取图片的六种正确姿势。所以记得opencv文档里有这样的描述:
imread()还是很强大的,所以写个程序看看那这些人是什么样吧。
程序的功能就是打开电脑摄像头,当P键按下(P是拍照的首字母?还是Photo的首字母?还是Picture的首字母?)的时候,保存当前帧的图像。简单到没朋友(竟然耗费了那么久!)。
然后我们就可以运行程序,不停地按下p键对自己一通狂拍了。
人脸检测在之前的博客中已经做了介绍,这里就不再赘述。详情参考:OpenCV实践之路——人脸检测(C++/Python)。用ROI分割即可。
检测出人脸之后改变大小使之与ORL人脸数据库人脸大小一致。通过加断点在Locals里面或者是ImageWatch可以看到ORL人脸数据库人脸的大小是92 x 112。
这里只需要对检测后得到的ROI做一次resize即可。
这两步的代码如下:
至此,我们就得到和ORL人脸数据库人脸大小一致的自己的人脸数据集。然后我们把自己的作为第41个人,在我们下载的人脸文件夹下建立一个s41的子文件夹,把自己的人脸数据放进去。就成了这样下面这样,最后一个文件夹里面是我自己的头像照片:
最后那个at.txt放到下一次再说,训练模型就靠它了。
这里有一点值得注意:我这里保存的图像格式是.jpg的,而不是跟原数据集一样是.pgm的。经测试仍然可以训练出可以正确识别我自己人脸的模型来。但是如果大小不一致会报错。
人脸检测可以利用opencv自带的分类器,但是人脸识别就需要自己收集数据,自己训练分类器了。opencv给出的有人脸识别的教程:Face Recognition with OpenCV。网上也可以找到中文版本的。
一、背景数据集
本次用的数据集市opencv给出的教程里面的第一个数据集:The AT&T Facedatabase。又称ORL人脸数据库,40个人,每人10张照片。照片在不同时间、不同光照、不同表情(睁眼闭眼、笑或者不笑)、不同人脸细节(戴眼镜或者不戴眼镜)下采集。所有的图像都在一个黑暗均匀的背景下采集的,正面竖直人脸(有些有有轻微旋转)。下载下来之后是这样的:
可以看到每个人一个文件夹,每个文件夹下是这个人的十张照片,但是不是我们熟悉的BMP或者是PNG或者是JPEG格式的,而是PGM格式的。windows7自带的照片查看器和画图软件都不能打开这种格式的图片。不过好在我昨天刚对imread()函数研究过:使用imread()函数读取图片的六种正确姿势。所以记得opencv文档里有这样的描述:
imread()还是很强大的,所以写个程序看看那这些人是什么样吧。
二、自己的人脸数据集
1、拍照程序
想要识别自己,单有别人的数据集还是不行的,还需要自己人脸的照片才行。这就需要我们收集自己的照片,然后和上面的那个数据集一起来训练模型。在拿着手机自拍的过程中我想到,问什么不写一个程序用电脑的摄像头自拍呢,随便还能研究下怎么用opencv实现拍照的功能。经过一番实验(其实还是费了好长时间),终于写了一个拍照程序。程序的功能就是打开电脑摄像头,当P键按下(P是拍照的首字母?还是Photo的首字母?还是Picture的首字母?)的时候,保存当前帧的图像。简单到没朋友(竟然耗费了那么久!)。
C++
#include <opencv.hpp> #include <string> using namespace cv; int main(int argc, char** argv) { // 打开视频 string sourceReference="E:\\test3\\vedio\\vtest.avi"; VideoCapture cap(sourceReference); //如果是摄像头 // VideoCapture cap(0); if(!cap.isOpened()) return -1; Mat frame; int i=0; while (1) { char key = waitKey(100); cap >> frame; if (frame.empty()) { return -1; } imshow("frame", frame); string filename = format("D:\\pic%d.jpg", i); if (key=='q' || key==27) break; switch (key) { case'p': i++; imwrite(filename, frame); imshow("photo", frame); waitKey(500); destroyWindow("photo"); break; default: break; } } destroyAllWindows(); cap.release(); return 0; }
然后我们就可以运行程序,不停地按下p键对自己一通狂拍了。
python
# -*- coding: UTF-8 -*- import cv2 # 打开视频 sourceReference=r"E:\\test3\\vedio\\vtest.avi" cap=cv2.VideoCapture(sourceReference) # 如果是摄像头 # cap=cv2.VideoCapture(0) if not cap.isOpened():exit(-1) i=0 while(1): ret,frame=cap.read() if not ret:exit(-1) cv2.imshow('frame',frame) key=cv2.waitKey(60) & 0xff if key==27 or key==ord('q'):break filename = r"D:\\pic{0}.jpg".format(i) # filename = r"D:\\pic%d.jpg"%(i) if key==ord('p'): i+=1 cv2.imwrite(filename,frame) cv2.imshow('photo',frame) cv2.waitKey(300) cv2.destroyWindow('photo') cv2.destroyAllWindows() cap.release()
2、预处理
在得到自己的人脸照片之后,还需要对这些照片进行一些预处理才能拿去训练模型。所谓预处理,其实就是检测并分割出人脸,并改变人脸的大小与下载的数据集中图片大小一致。人脸检测在之前的博客中已经做了介绍,这里就不再赘述。详情参考:OpenCV实践之路——人脸检测(C++/Python)。用ROI分割即可。
检测出人脸之后改变大小使之与ORL人脸数据库人脸大小一致。通过加断点在Locals里面或者是ImageWatch可以看到ORL人脸数据库人脸的大小是92 x 112。
这里只需要对检测后得到的ROI做一次resize即可。
这两步的代码如下:
#include <opencv.hpp> #include <string> using namespace cv; int main(int argc, char** argv) { Mat img; std::vector<Rect> faces; Mat img_gray; string filename="E:\\test3\\image\\messi_2.jpg"; img=imread(filename); cvtColor(img, img_gray, COLOR_BGR2GRAY); equalizeHist(img_gray, img_gray); // 直方图均衡 //-- Detect faces String face_cascade_name = "E:\\test3\\data\\haarcascade_frontalface_default.xml"; CascadeClassifier face_cascade; //定义人脸分类器 //-- 1. Load the cascades if (!face_cascade.load(face_cascade_name)){ printf("--(!)Error loading face cascade\n"); return -1; }; face_cascade.detectMultiScale(img_gray, faces, 1.1, 3, CV_HAAR_DO_ROUGH_SEARCH, Size(50, 50)); for (size_t j = 0; j < faces.size(); j++) { Mat faceROI = img(faces[j]); Mat MyFace; if (faceROI.cols > 100) { resize(faceROI, MyFace, Size(92, 112)); string str = format("D:\\MyFcae%d.jpg", j); imwrite(str, MyFace); imshow("ii", MyFace); } int c = waitKey(5000); if ((char)c == 27) { return 0; } // escape } destroyAllWindows(); return 0; }
至此,我们就得到和ORL人脸数据库人脸大小一致的自己的人脸数据集。然后我们把自己的作为第41个人,在我们下载的人脸文件夹下建立一个s41的子文件夹,把自己的人脸数据放进去。就成了这样下面这样,最后一个文件夹里面是我自己的头像照片:
最后那个at.txt放到下一次再说,训练模型就靠它了。
这里有一点值得注意:我这里保存的图像格式是.jpg的,而不是跟原数据集一样是.pgm的。经测试仍然可以训练出可以正确识别我自己人脸的模型来。但是如果大小不一致会报错。
相关文章推荐
- 【opencv实践】人脸识别匹配——数据收集和预处理
- OpenCV人脸识别之一:数据收集和预处理
- OpenCV实践之路——人脸识别之二模型训练
- OpenCV实践之路——人脸识别之一数据收集和预处理
- OpenCV实践之路——人脸识别之三识别自己的脸
- OpenCV实践之路——人脸识别之二模型训练
- OpenCV实践之路——人脸检测(C++/Python) 【转】
- opencv读取视频数据输出人脸识别结果
- android jni中将大数据回调到java层的时候用法,比如视频流,音频流等,图片流等 比如我用ffmpeg解码好视频流,想送到java层使用opengGL进行显示,opencv进行人脸识别等等
- OpenCV实践之路——用OpenCV和Dlib进行人脸颜值预测(Python)
- OpenCV实践之路——人脸检测(C++/Python)
- OpenCV人脸识别之实践篇
- 用opencv读取摄像头数据实现人脸识别
- 【opencv实践】人脸识别匹配——模型训练
- 人脸识别《一》opencv人脸识别之预处理
- OpenCV实践之路——人脸检测(C++/Python)
- [opencv][python][scikit-learn]att_faces数据人脸识别
- OpenCV实践之路——用dlib库进行人脸检测与人脸标记(Python)
- 人脸识别《一》opencv人脸识别之收集人脸并学习
- 人脸识别---光照预处理(Opencv代码和Matlab代码)