1.准备训练数据

网络上下载(训练数据量大时,通过爬虫获取)目标的图片:
运用以下代码将原图中的人脸头像识别、提取、调整大小(这里是150*200),并分别保存。
运行环境:win7 64+VS2013+openCV3.1。
(PS:抱怨下vs和opencv的版本密切相关,注意安装配置)
  
#include <opencv2\opencv.hpp>
#include <iostream>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>#include <opencv2/imgproc/types_c.h>
#include <opencv2/videoio/videoio_c.h>
#include <opencv2/highgui/highgui_c.h>using namespace std;
using namespace cv;/** Function Headers */
void detectAndDisplay(Mat frame);/** Global variables */
String face_cascade_name = "F:\\Downloads\\opencv_build\\install\\etc\\haarcascades\\haarcascade_frontalface_default.xml";
String eyes_cascade_name = "F:\\Downloads\\opencv_build\\install\\etc\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;   //定义人脸分类器
CascadeClassifier eyes_cascade;   //定义人眼分类器
String window_name = "Capture - Face detection";/** @function main */
int main(void)
{//-- 1. Load the cascadesif (!face_cascade.load(face_cascade_name)){ printf("--(!)Error loading face cascade\n"); return -1; };if (!eyes_cascade.load(eyes_cascade_name)){ printf("--(!)Error loading eyes cascade\n"); return -1; };//-- 2. 遍历原图像文件夹vector<String> files;glob("D:\\training\\liudh_before\\*.jpg", files, true);//-- 3. 识别、提取,并保存头像至新文件夹。图片均调整为150x200像素for (int i = 0; i < files.size(); i++){//Image processing  Mat img = imread(files[i]); //读取文件cout << files[i] << '\n';detectAndDisplay(img);     //提取头像waitKey(1000);}
}/** @function detectAndDisplay */
void detectAndDisplay(Mat frame)
{static int count = 0;std::vector<Rect> faces;Mat frame_gray;Mat MyFace;cvtColor(frame, frame_gray, COLOR_BGR2GRAY);//equalizeHist(frame_gray, frame_gray);//imshow("2", frame_gray);//-- Detect facesface_cascade.detectMultiScale(frame_gray, faces, 1.1);for (size_t i = 0; i < faces.size(); i++)  //人脸数目{Mat faceROI = frame_gray(faces[i]);rectangle(frame, faces[i], Scalar(255, 0, 0), 2, 8, 0);if (faceROI.cols > 80){resize(faceROI, MyFace, Size(150, 200));string  str = format("D:\\training\\liudh\\MyFcae%d.jpg", count);cout << " 保存图片" << count<<endl;imwrite(str, MyFace);imshow("ii", MyFace);}count++;}//-- Show what you gotnamedWindow(window_name, 2);imshow(window_name, frame);
}

2.制作标签文件CSV

进入命令行,输入命令 di /b/s *.pgm *jpg >at.txt
会在训练数据文件夹下生成一个at.txt文件,但这文件内只有数据,没有标签。(笨办法是将数据拷贝到execl表格中生成标签)
最终生成文件内容如下所示:
也可以通过create_csv.py制作标签(注意修改文件中的目录路径)
#!/usr/bin/env pythonimport sys
import os.path# This is a tiny script to help you creating a CSV file from a face
# database with a similar hierarchie:
#
#  philipp@mango:~/facerec/data/at$ tree
#  .
#  |-- README
#  |-- s1
#  |   |-- 1.pgm
#  |   |-- ...
#  |   |-- 10.pgm
#  |-- s2
#  |   |-- 1.pgm
#  |   |-- ...
#  |   |-- 10.pgm
#  ...
#  |-- s40
#  |   |-- 1.pgm
#  |   |-- ...
#  |   |-- 10.pgm
#if __name__ == "__main__":#if len(sys.argv) != 2:#    print "usage: create_csv <base_path>"#    sys.exit(1)#BASE_PATH=sys.argv[1]BASE_PATH="D:/att_faces"SEPARATOR=";"fh = open("D:/att_faces/at.txt",'w')label = 1 for dirname, dirnames, filenames in os.walk(BASE_PATH):for subdirname in dirnames:subject_path = os.path.join(dirname, subdirname)for filename in os.listdir(subject_path):abs_path = "%s/%s" % (subject_path, filename)#print "%s%s%d" % (abs_path, SEPARATOR, label)fh.write(abs_path)fh.write(SEPARATOR)fh.write(str(label))fh.write("\n")      label = label + 1fh.close()

3. 训练模型

EigenFace和FisherFace的训练图像和测试图像都必须是灰度图,而且是经过归一化裁剪过的。
   
   1.运用alt.txt文件,加载训练数据;提取数据和标签
   2.根据FaceRecognizer三种训练模型进行训练;
   3.保存训练数据及模型(xml)
//#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>
#include <sstream>
#include <math.h>#include <opencv2/face.hpp>
#include <opencv2/face/facerec.hpp>
#include <iostream>
#include <stdio.h>
#include "opencv2/core.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/calib3d.hpp"
#include "opencv2/imgproc.hpp"
#include"opencv2/flann.hpp"
#include"opencv2/xfeatures2d.hpp"
#include"opencv2/ml.hpp"
#include"opencv2/face.hpp"
#include"opencv2/face/facerec.hpp"
#include"opencv2/objdetect.hpp"using namespace cv;
using namespace std;
using namespace face;static Mat norm_0_255(InputArray _src) {Mat src = _src.getMat();// 创建和返回一个归一化后的图像矩阵:Mat dst;switch (src.channels()) {case1:cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);break;case3:cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC3);break;default:src.copyTo(dst);break;}return dst;
}//使用CSV文件去读图像和标签,主要使用stringstream和getline方法
static void read_csv(const string& filename, vector<Mat>& images, 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()));}}
}int main()
{//读取你的CSV文件路径.//string fn_csv = string(argv[1]);string fn_csv = "D:\\training\\at.txt";// 2个容器来存放图像数据和对应的标签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);}// 下面的几行代码仅仅是从你的数据集中移除最后一张图片//[gm:自然这里需要根据自己的需要修改,他这里简化了很多问题]Mat testSample = images[images.size() - 1];int testLabel = labels[labels.size() - 1];images.pop_back();labels.pop_back();// 下面几行创建了一个特征脸模型用于人脸识别,// 通过CSV文件读取的图像和标签训练它。// T这里是一个完整的PCA变换//如果你只想保留10个主成分,使用如下代码//      cv::createEigenFaceRecognizer(10);//// 如果你还希望使用置信度阈值来初始化,使用以下语句://      cv::createEigenFaceRecognizer(10, 123.0);//// 如果你使用所有特征并且使用一个阈值,使用以下语句://      cv::createEigenFaceRecognizer(0, 123.0);Ptr <FaceRecognizer> model = createEigenFaceRecognizer(10);model->train(images, labels);model->save("MyFacePCAModel.xml");Ptr <FaceRecognizer> model1 = createFisherFaceRecognizer(10);model1->train(images, labels);model1->save("MyFaceFisherModel.xml");Ptr <FaceRecognizer> model2 = createLBPHFaceRecognizer(10);model2->train(images, labels);model2->save("MyFaceLBPHModel.xml");// 下面对测试图像进行预测,predictedLabel是预测标签结果int predictedLabel = model->predict(testSample);int predictedLabel1 = model1->predict(testSample);int predictedLabel2 = model2->predict(testSample);// 还有一种调用方式,可以获取结果同时得到阈值://      int predictedLabel = -1;//      double confidence = 0.0;//      model->predict(testSample, predictedLabel, confidence);string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel);string result_message1 = format("Predicted class = %d / Actual class = %d.", predictedLabel1, testLabel);string result_message2 = format("Predicted class = %d / Actual class = %d.", predictedLabel2, testLabel);cout << result_message << endl;cout << result_message1 << endl;cout << result_message2 << endl;while (1);//waitkey只对imshow有效//if (waitKey(10) == 17) return 0;; ////return 0;
}
4. 预测数据
    加载上述训练好的训练模型,并进行估值
   
#include<opencv2\opencv.hpp>
#include<iostream>
#include <opencv2\opencv.hpp>
#include <iostream>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>#include <opencv2/imgproc/types_c.h>
#include <opencv2/videoio/videoio_c.h>
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/face.hpp>
#include <opencv2/face/facerec.hpp>using namespace std;
using namespace cv;
using namespace face;int main()
{VideoCapture cap("D:\\pics\\wjd.avi");    //打开默认摄像头if (!cap.isOpened()){return -1;}Mat frame;Mat edges;Mat gray;CascadeClassifier cascade;bool stop = false;//训练好的文件名称,放置在可执行文件同目录下cascade.load("D:\\training\\training_data\\haarcascade_frontalface_default.xml");Ptr<FaceRecognizer> modelPCA = createEigenFaceRecognizer();modelPCA->load("D:\\training\\training_data\\MyFacePCAModel.xml");while (!stop){cap >> frame;//frame = imread("D:\\pics\\test3.jpg");if (frame.empty()) break;//建立用于存放人脸的向量容器vector<Rect> faces(0);cvtColor(frame, gray, CV_BGR2GRAY);//改变图像大小,使用双线性差值//resize(gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR);//变换后的图像进行直方图均值化处理equalizeHist(gray, gray);cascade.detectMultiScale(gray, faces,1.1);//, 2, 0//|CV_HAAR_FIND_BIGGEST_OBJECT//|CV_HAAR_DO_ROUGH_SEARCH//| CV_HAAR_SCALE_IMAGE,//Size(30, 30));Mat face;Point text_lb;for (size_t i = 0; i < faces.size(); i++){if (faces[i].height > 0 && faces[i].width > 0){face = gray(faces[i]);text_lb = Point(faces[i].x, faces[i].y);rectangle(frame, faces[i], Scalar(255, 0, 0), 1, 8, 0);}}imshow("face1", frame);Mat face_test;int predictPCA = 0;if (face.rows >= 80){resize(face, face_test, Size(150, 200));}//Mat face_test_gray;//cvtColor(face_test, face_test_gray, CV_BGR2GRAY);if (!face_test.empty()){//测试图像应该是灰度图predictPCA = modelPCA->predict(face_test);}cout << predictPCA << endl;if (predictPCA == 1){string name = "liangcw";putText(frame, name, text_lb, FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255));}else if (predictPCA == 2){string name = "liudh";putText(frame, name, text_lb, FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255));}else if (predictPCA == 3){string name = "zyw";putText(frame, name, text_lb, FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255));}else if (predictPCA == 4){string name = "zzy";putText(frame, name, text_lb, FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255));}imshow("face2", frame);//waitKey(0);if (waitKey(10) >= 0)stop = true;}return 0;
}
5. 测试结果
优酷下载了《演员的诞生》某片段,转成avi格式,能识别出视频中的周一围、章子怡等
6. 结论
基于openCV人脸识别的相关结构体(CascaderClassify、FacerRecognizer),训练数据越大识别效果才越好
人脸检测相关模型,如正脸、侧脸、眼睛、鼻子都是分开的,有没有联合一起的??

基于openCV的视频人脸识别——演员的诞生视频人脸识别相关推荐

  1. 基于OpenCV&ORB和特征匹配的双视频图像拼接(源码&部署教程)

    1.双视频拼接效果展示 2.视频演示 [项目分享]Python基于OpenCV&ORB和特征匹配的双视频图像拼接(源码&部署教程)_哔哩哔哩_bilibili 3.背景 随着汽车电子和 ...

  2. Python基于OpenCV&ORB和特征匹配的双视频图像拼接(源码&部署教程)

    1.双视频拼接效果展示 2.视频演示 [项目分享]Python基于OpenCV&ORB和特征匹配的双视频图像拼接(源码&部署教程)_哔哩哔哩_bilibili 3.背景 随着汽车电子和 ...

  3. python 摄像头录制帧率_基于opencv和python的可变帧速率IP摄像机视频记录

    首先,我想对我正在做的事情发表评论.在 我有一个IP摄像机通过一个带以太网线的路由器连接到我的网络(FOSCAM 9800p),我试图用RTSP协议录制一段视频.我未来的打算是用opencv在中间添加 ...

  4. 基于opencv的行人检测(支持图片,视频)

    基于方向梯度直方图(HOG)/线性支持向量机(SVM)算法的行人检测方法中存在检测速度慢的问题,如下图所示,对一张400*490像素的图片进行检测要接近800毫秒,所以hog+svm的方法放在视频中进 ...

  5. C++基于OpenCV实现实时监控和运动检测记录

    基于OpenCV实现实时监控并通过运动检测记录视频 一.课程介绍 1. 课程来源 课程使用的操作系统为 Ubuntu 14.04,OpenCV 版本为OpenCV 2.4.13.1,你可以在这里查看该 ...

  6. 【优秀课设】基于OpenCV的Python人脸识别、检测、框选(遍历目录下所有照片依次识别 视频随时标注)

    基于OpenCV的Python人脸识别.检测.框选 (遍历目录下所有照片依次识别 视频随时标注) 移步: https://blog.csdn.net/weixin_53403301/article/d ...

  7. 基于OpenCV的人脸识别自助商店(源码&部署视频)

    1.模块功能介绍 实现人脸识别模块.人脸登录与注册功能.商店显示和用户余额页显示功能 用GUl图形界面实现(pyqt)语言python windows下软件pycharm 1.用户登录模块:刷脸登录 ...

  8. Python基于OpenCV的人脸识别自助商店(源码&部署视频)

    1.模块功能介绍 实现人脸识别模块.人脸登录与注册功能.商店显示和用户余额页显示功能 用GUl图形界面实现(pyqt)语言python windows下软件pycharm 1.用户登录模块:刷脸登录 ...

  9. 调用笔记本的摄像头实现基于opencv的视频人脸识别(中文显示和英文显示)以及 index 480 is out of bounds for axis 0 with size 480错误的解决

    @人脸识别代码和一些常见错误 基于opencv的视频人脸识别(中文显示)以及 index 480 is out of bounds for axis 0 with size 480错误的解决 参考了 ...

最新文章

  1. 3.15计算机网络原理与技术笔记
  2. C++创建一个特殊的类
  3. 再见了古诺。 你好Drools工作台。
  4. php memcache 类库,php操作Memcache的一个类库的方法(代码)
  5. 面试开发可以用python_Python开发工程师面试题(五)
  6. javafx给图形上颜色_红牛商标无效案:新欧盟商标条例下如何满足颜色商标注册条件?...
  7. springboot房屋租赁管理系统
  8. html 设置表格打印宽度设置,html表格怎么设置宽度
  9. 利用QGIS提取天地图矢量底图中的建筑模型边界线
  10. [实战] Android 发短信 - SMS
  11. 统计字符号串“aaaabbbccccddfggh”中字母个数或统计最多字母数;
  12. Shell脚本自动源码包安装LA/NMP架构详解(赠软件包+脚本)
  13. AtCoder Beginner Contest 208
  14. zabbix用户和组权限、admin密码的修改
  15. pytorch,cuda,cudatoolkit,driver版本详解
  16. python和plc哪个难_PLC是学西门子的好还是学三菱的?
  17. MySQL创建联合索引,字段的先后顺序,对查询的影响分析
  18. c语言水平制表符作用,C语言课:VC6.0中水平制表符和退格符的进一步说明
  19. 如何打开docx文件
  20. PHP for循环执行流程

热门文章

  1. 物联网技术lora的简介和应用
  2. linux 下 kmplayer 安装。。
  3. 利用DOS命令压缩、解压文件
  4. 这是修养还是管理艺术
  5. appletviewer用法
  6. android不支持USB怎么办,安卓手机usb不能用 手机找不到USB调试模式怎么解决?
  7. RLC串联电路的一些形象化的结算
  8. PHP传说中的三码合一
  9. J_link无法调试
  10. 近世代数--唯一分解整环上的多项式环--本原多项式的可约问题