opencv 人脸识别 (一)训练样本的处理
本文实现基于eigenface的人脸检测与识别。给定一个图像数据库,进行以下步骤:
- 进行人脸检测,将检测出的人脸存入数据库2
- 对数据库2进行人脸建模
- 在测试集上进行recognition
- 进行人脸检测,将检测出的人脸存入数据库2
环境:vs2010+opencv 2.4.6.0
特征:eigenface
Input:一个人脸数据库,15个人,每人20个样本(左右)。
Output:人脸检测,并识别出每张检测到的人脸。
===============================
本文完成第一步,数据预处理:自动检测所有文件夹中每个sample中的人脸,作为训练数据。
Input:一个color文件夹,每个文件夹中有1~N这N个子文件夹,每个子文件夹内有n张包括第n类人的照片,如图。
最终结果:
核心:face detection(detectAndDraw)
辅助:截图并保存部分图片(CutImg),文件夹内图片遍历(read_img),图片转换成相同大小(normalizeone)
括号内分别是函数名,下面分别给出代码及说明。
1. 遍历文件夹:CBrowseDir类和CStatDir类(具体见这篇),三个文件如下:
1.1 BrowseDir.h
![](https://code.csdn.net/assets/CODE_ico.png)
- #pragma once
- #include "direct.h"
- #include "string.h"
- #include "io.h"
- #include "stdio.h"
- #include <vector>
- #include <iostream>
- using namespace std;
- class CBrowseDir
- {
- protected:
- char m_szInitDir[_MAX_PATH];
- public:
- CBrowseDir();
- bool SetInitDir(const char *dir);
- bool BeginBrowse(const char *filespec);
- vector<char*> BeginBrowseFilenames(const char *filespec);
- protected:
- bool BrowseDir(const char *dir,const char *filespec);
- vector<char*> GetDirFilenames(const char *dir,const char *filespec);
- virtual bool ProcessFile(const char *filename);
- virtual void ProcessDir(const char *currentdir,const char *parentdir);
- };
1.2 BrowseDir.cpp
![](https://code.csdn.net/assets/CODE_ico.png)
- #include "BrowseDir.h"
- #include "direct.h"
- #include "string.h"
- #include "io.h"
- #include "stdio.h"
- #include <vector>
- #include <iostream>
- using namespace std;
- CBrowseDir::CBrowseDir()
- {
- getcwd(m_szInitDir,_MAX_PATH);
- int len=strlen(m_szInitDir);
- if (m_szInitDir[len-1] != '\\')
- strcat(m_szInitDir,"\\");
- }
- bool CBrowseDir::SetInitDir(const char *dir)
- {
- if (_fullpath(m_szInitDir,dir,_MAX_PATH) == NULL)
- return false;
- if (_chdir(m_szInitDir) != 0)
- return false;
- int len=strlen(m_szInitDir);
- if (m_szInitDir[len-1] != '\\')
- strcat(m_szInitDir,"\\");
- return true;
- }
- vector<char*>CBrowseDir:: BeginBrowseFilenames(const char *filespec)
- {
- ProcessDir(m_szInitDir,NULL);
- return GetDirFilenames(m_szInitDir,filespec);
- }
- bool CBrowseDir::BeginBrowse(const char *filespec)
- {
- ProcessDir(m_szInitDir,NULL);
- return BrowseDir(m_szInitDir,filespec);
- }
- bool CBrowseDir::BrowseDir(const char *dir,const char *filespec)
- {
- _chdir(dir);
- long hFile;
- _finddata_t fileinfo;
- if ((hFile=_findfirst(filespec,&fileinfo)) != -1)
- {
- do
- {
- if (!(fileinfo.attrib & _A_SUBDIR))
- {
- char filename[_MAX_PATH];
- strcpy(filename,dir);
- strcat(filename,fileinfo.name);
- cout << filename << endl;
- if (!ProcessFile(filename))
- return false;
- }
- } while (_findnext(hFile,&fileinfo) == 0);
- _findclose(hFile);
- }
- _chdir(dir);
- if ((hFile=_findfirst("*.*",&fileinfo)) != -1)
- {
- do
- {
- if ((fileinfo.attrib & _A_SUBDIR))
- {
- if (strcmp(fileinfo.name,".") != 0 && strcmp
- (fileinfo.name,"..") != 0)
- {
- char subdir[_MAX_PATH];
- strcpy(subdir,dir);
- strcat(subdir,fileinfo.name);
- strcat(subdir,"\\");
- ProcessDir(subdir,dir);
- if (!BrowseDir(subdir,filespec))
- return false;
- }
- }
- } while (_findnext(hFile,&fileinfo) == 0);
- _findclose(hFile);
- }
- return true;
- }
- vector<char*> CBrowseDir::GetDirFilenames(const char *dir,const char *filespec)
- {
- _chdir(dir);
- vector<char*>filename_vec;
- filename_vec.clear();
- long hFile;
- _finddata_t fileinfo;
- if ((hFile=_findfirst(filespec,&fileinfo)) != -1)
- {
- do
- {
- if (!(fileinfo.attrib & _A_SUBDIR))
- {
- char *filename = new char[_MAX_PATH];
- strcpy(filename,dir);
- //int st = 0; while (dir[st++]!='\0');
- strcat(filename,fileinfo.name); //filename[st]='\0';
- filename_vec.push_back(filename);
- }
- } while (_findnext(hFile,&fileinfo) == 0);
- _findclose(hFile);
- }
- _chdir(dir);
- if ((hFile=_findfirst("*.*",&fileinfo)) != -1)
- {
- do
- {
- if ((fileinfo.attrib & _A_SUBDIR))
- {
- if (strcmp(fileinfo.name,".") != 0 && strcmp
- (fileinfo.name,"..") != 0)
- {
- char subdir[_MAX_PATH];
- strcpy(subdir,dir);
- strcat(subdir,fileinfo.name);
- strcat(subdir,"\\");
- ProcessDir(subdir,dir);
- return GetDirFilenames(subdir,filespec);
- }
- }
- } while (_findnext(hFile,&fileinfo) == 0);
- _findclose(hFile);
- }
- return filename_vec;
- }
- bool CBrowseDir::ProcessFile(const char *filename)
- {
- return true;
- }
- void CBrowseDir::ProcessDir(const char
- *currentdir,const char *parentdir)
- {
- }
1.3 StatDir.h
![](https://code.csdn.net/assets/CODE_ico.png)
- #pragma once
- #include "browsedir.h"
- class CStatDir:public CBrowseDir
- {
- protected:
- int m_nFileCount; //保存文件个数
- int m_nSubdirCount; //保存子目录个数
- public:
- CStatDir()
- {
- m_nFileCount=m_nSubdirCount=0;
- }
- int GetFileCount()
- {
- return m_nFileCount;
- }
- int GetSubdirCount()
- {
- return m_nSubdirCount-1;
- }
- protected:
- virtual bool ProcessFile(const char *filename)
- {
- m_nFileCount++;
- return CBrowseDir::ProcessFile(filename);
- }
- virtual void ProcessDir
- (const char *currentdir,const char *parentdir)
- {
- m_nSubdirCount++;
- CBrowseDir::ProcessDir(currentdir,parentdir);
- }
- };
2. 辅助函数Prehelper.h, Prehelper.cpp:负责返回文件夹内所有图片(read_img),检测人脸(detectAndDraw并可以在原图中画出),截图(CutImg),提取(DetectandExtract)
2.1 Prehelper.h
![](https://code.csdn.net/assets/CODE_ico.png)
- //preprocessing helper
- //@ Author : Rachel-Zhang
- #include "opencv2/core/core.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include "opencv2/contrib/contrib.hpp"
- #include <cv.h>
- #include <vector>
- #include <utility>
- using namespace cv;
- using namespace std;
- void normalizeone(const char* dir,IplImage* standard);
- void CutImg(IplImage* src, CvRect rect,IplImage* res);
- vector<Rect> detectAndDraw( Mat& img, CascadeClassifier& cascade,
- CascadeClassifier& nestedCascade,
- double scale, bool tryflip,bool draw );
- IplImage* DetectandExtract(Mat& img, CascadeClassifier& cascade,
- CascadeClassifier& nestedCascade,
- double scale, bool tryflip);
- int read_img(const string& dir, vector<Mat> &images);
- vector<pair<char*,Mat>> read_img(const string& dir);
2.2 Prehelper.cpp
![](https://code.csdn.net/assets/CODE_ico.png)
- #include "Prehelper.h"
- #include "BrowseDir.h"
- #include "StatDir.h"
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <cv.h>
- using namespace cv;
- void normalizeone(const char* dir,IplImage* standard)
- {
- CStatDir statdir;
- if (!statdir.SetInitDir(dir))
- {
- puts("Dir not exist");
- return;
- }
- vector<char*>file_vec = statdir.BeginBrowseFilenames("*.*");
- int i;
- for (i=0;i<file_vec.size();i++)
- {
- IplImage* cur_img = cvLoadImage(file_vec[i],CV_LOAD_IMAGE_GRAYSCALE);
- //IplImage*cur_gray = cvCreateImage(cvGetSize(cur_img),cur_img->depth,1);
- cvResize(cur_img,standard,CV_INTER_AREA);
- //cvCvtColor(standard,cur_gray,CV_RGB2GRAY);
- // cvNamedWindow("cur_img",CV_WINDOW_AUTOSIZE);
- // cvNamedWindow("standard",CV_WINDOW_AUTOSIZE);
- // cvShowImage("cur_img",cur_img);
- // cvShowImage("standard",standard);
- // cvWaitKey();
- cvSaveImage(file_vec[i],cur_img);
- }
- }
- void CutImg(IplImage* src, CvRect rect,IplImage* res)
- {
- CvSize imgsize;
- imgsize.height = rect.height;
- imgsize.width = rect.width;
- cvSetImageROI(src,rect);
- cvCopy(src,res);
- cvResetImageROI(res);
- }
- int read_img(const string& dir, vector<Mat> &images)
- {
- CStatDir statdir;
- if (!statdir.SetInitDir(dir.c_str()))
- {
- cout<<"Direct "<<dir<<" not exist!"<<endl;
- return 0;
- }
- int cls_id = dir[dir.length()-1]-'0';
- vector<char*>file_vec = statdir.BeginBrowseFilenames("*.*");
- int i,s = file_vec.size();
- for (i=0;i<s;i++)
- {
- Mat graymat = imread(file_vec[i],0);
- //graymat.reshape(1,1);//flatten to one row
- images.push_back(graymat);
- }
- return s;
- }
- vector<pair<char*,Mat>> read_img(const string& dir)
- {
- CStatDir statdir;
- pair<char*,Mat> pfi;
- vector<pair<char*,Mat>> Vp;
- if (!statdir.SetInitDir(dir.c_str()))
- {
- cout<<"Direct "<<dir<<" not exist!"<<endl;
- return Vp;
- }
- int cls_id = dir[dir.length()-1]-'0';
- vector<char*>file_vec = statdir.BeginBrowseFilenames("*.*");
- int i,s = file_vec.size();
- for (i=0;i<s;i++)
- {
- pfi.first = file_vec[i];
- pfi.second = imread(file_vec[i]);
- Vp.push_back(pfi);
- }
- return Vp;
- }
- vector<Rect> detectAndDraw( Mat& img, CascadeClassifier& cascade,
- CascadeClassifier& nestedCascade,
- double scale, bool tryflip, bool draw )
- {
- int i = 0;
- double t = 0;
- vector<Rect> faces, faces2;
- const static Scalar colors[] = { CV_RGB(0,0,255),
- CV_RGB(0,128,255),
- CV_RGB(0,255,255),
- CV_RGB(0,255,0),
- CV_RGB(255,128,0),
- CV_RGB(255,255,0),
- CV_RGB(255,0,0),
- CV_RGB(255,0,255)} ;
- Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );
- cvtColor( img, gray, CV_BGR2GRAY );
- resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );
- equalizeHist( smallImg, smallImg );
- t = (double)cvGetTickCount();
- cascade.detectMultiScale( smallImg, faces,
- 1.1, 2, 0
- |CV_HAAR_FIND_BIGGEST_OBJECT
- //|CV_HAAR_DO_ROUGH_SEARCH
- //|CV_HAAR_SCALE_IMAGE
- ,
- Size(30, 30) );
- if( tryflip )
- {
- flip(smallImg, smallImg, 1);
- cascade.detectMultiScale( smallImg, faces2,
- 1.1, 2, 0
- |CV_HAAR_FIND_BIGGEST_OBJECT
- //|CV_HAAR_DO_ROUGH_SEARCH
- //|CV_HAAR_SCALE_IMAGE
- ,
- Size(30, 30) );
- for( vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); r++ )
- {
- faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));
- }
- }
- t = (double)cvGetTickCount() - t;
- printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );
- if(draw)
- {
- for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ )
- {
- Mat smallImgROI;
- vector<Rect> nestedObjects;
- Point center;
- Scalar color = colors[i%8];
- int radius;
- double aspect_ratio = (double)r->width/r->height;
- rectangle( img, cvPoint(cvRound(r->x*scale), cvRound(r->y*scale)),
- cvPoint(cvRound((r->x + r->width-1)*scale), cvRound((r->y + r->height-1)*scale)),
- color, 3, 8, 0);
- if( nestedCascade.empty() )
- continue;
- smallImgROI = smallImg(*r);
- nestedCascade.detectMultiScale( smallImgROI, nestedObjects,
- 1.1, 2, 0
- |CV_HAAR_FIND_BIGGEST_OBJECT
- //|CV_HAAR_DO_ROUGH_SEARCH
- //|CV_HAAR_DO_CANNY_PRUNING
- //|CV_HAAR_SCALE_IMAGE
- ,
- Size(30, 30) );
- //draw eyes
- // for( vector<Rect>::const_iterator nr = nestedObjects.begin(); nr != nestedObjects.end(); nr++ )
- // {
- // center.x = cvRound((r->x + nr->x + nr->width*0.5)*scale);
- // center.y = cvRound((r->y + nr->y + nr->height*0.5)*scale);
- // radius = cvRound((nr->width + nr->height)*0.25*scale);
- // circle( img, center, radius, color, 3, 8, 0 );
- // }
- }
- cv::imshow( "result", img );
- }
- return faces;
- }
- IplImage* DetectandExtract(Mat& img, CascadeClassifier& cascade,
- CascadeClassifier& nestedCascade,
- double scale, bool tryflip)
- {
- vector<Rect> Rvec = detectAndDraw(img,cascade,nestedCascade,scale,tryflip,0);
- int i,maxxsize=0,id=-1,area;
- for (i=0;i<Rvec.size();i++)
- {
- area = Rvec[i].width*Rvec[i].height;
- if(maxxsize<area)
- {
- maxxsize = area;
- id = i;
- }
- }
- IplImage* transimg = cvCloneImage(&(IplImage)img);
- if(id!=-1)
- {
- CvSize imgsize;
- imgsize.height = Rvec[id].height;
- imgsize.width = Rvec[id].width;
- IplImage* res = cvCreateImage(imgsize,transimg->depth,transimg->nChannels);
- CutImg(transimg,Rvec[id],res);
- return res;
- }
- return NULL;
- }
3. 主函数
![](https://code.csdn.net/assets/CODE_ico.png)
- //Detect.cpp
- //Preprocessing - Detect, Cut and Save
- //@Author : Rachel-Zhang
- #include "opencv2/objdetect/objdetect.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include "opencv2/imgproc/imgproc.hpp"
- #include <cctype>
- #include <iostream>
- #include <iterator>
- #include <stdio.h>
- #include "BrowseDir.h"
- #include "StatDir.h"
- #include "Prehelper.h"
- using namespace std;
- using namespace cv;
- #define CAM 2
- #define PHO 1
- #define K 5
- string cascadeName = "E:/software/opencv2.4.6.0/data/haarcascades/haarcascade_frontalface_alt.xml";
- string nestedCascadeName = "E:/software/opencv2.4.6.0/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml";
- int main( )
- {
- CvCapture* capture = 0;
- Mat frame, frameCopy, image;
- string inputName;
- bool tryflip = false;
- int mode;
- CascadeClassifier cascade, nestedCascade;
- double scale = 1.0;
- if( !cascade.load( cascadeName ) ||!nestedCascade.load( nestedCascadeName))
- {
- cerr << "ERROR: Could not load classifier cascade or nestedCascade" << endl;//若出现该问题请去检查cascadeName,可能是opencv版本路径问题
- return -1;
- }
- // printf("select the mode of detection: \n1: from picture\t 2: from camera\n");
- // scanf("%d",&mode);
- char** pics = (char**) malloc(sizeof*pics);
- /************************************************************************/
- /* detect face and save */
- /************************************************************************/
- int i,j;
- cout<<"detect and save..."<<endl;
- const char dir[256] = "D:\\Face_recognition\\pic\\";
- string cur_dir;
- char id[5];
- for(i=1; i<=K; i++)
- {
- cur_dir = dir;
- _itoa(i,id,10);
- cur_dir.append("color\\");
- cur_dir.append(id);
- vector<pair<char*,Mat>> imgs=read_img(cur_dir);
- for(j=0;j<imgs.size();j++)
- {
- IplImage* res = DetectandExtract(imgs[j].second,cascade,nestedCascade,scale,tryflip);
- if(res)
- cvSaveImage(imgs[j].first,res);
- }
- }
- return 0;
- }
正确的输出就是一系列人脸检测时间,且原文件夹内的图片变成了检测出的人脸(如上面结果图所示)。
文章所用代码打包链接:http://download.csdn.net/detail/abcjennifer/7047853
from: http://blog.csdn.net/abcjennifer/article/details/20446077
opencv 人脸识别 (一)训练样本的处理相关推荐
- opencv 全志_移植opencv人脸识别到全志A10开发板上 +linux3.0内核
移植opencv人脸识别 libz: zlib-1.2.3 libjpeg: jpegsrc.v6b libpng: libpng-1.2.18 libyasm: yasm-0.7. ...
- python人脸照片分类_Python OpenCV 人脸识别(一)
前面介绍了Numpy模块,下面再介绍一个OpenCV模块,就基于这两个库看一下当下很火的人工智能是如何实现的,我们介绍几个:人脸识别(当下非常火的).音视频操作等等.今天先介绍一下静态图片的人脸识别, ...
- 图像识别——(java)opencv(人脸识别简单实现)
人脸识别 package com.acts.opencv.demo;import javax.servlet.http.HttpServletRequest; import javax.servlet ...
- Python+OpenCV人脸识别签到考勤系统(新手入门)
Python+OpenCV人脸识别签到考勤系统(新手入门) 前言 项目效果图 项目需要的环境 编译器 辅助开发QT-designer 项目配置 代码部分 核心代码 项目目录结构 后记 正式版改进 项目 ...
- python opencv人脸识别考勤系统的完整源码
这篇文章主要介绍了python opencv人脸识别考勤系统的完整源码,本文给大家介绍的非常详细,希望对大家的学习或工作具有一定的参考借鉴价值. 代码如下: import wx import wx.g ...
- openCV人脸识别简单案例
1 基础 我们使用机器学习的方法完成人脸检测,首先需要大量的正样本图像(面部图像)和负样本图像(不含面部的图像)来训练分类器.我们需要从其中提取特征.下图中的 Haar 特征会被使用,就像我们的卷积核 ...
- 【opencv人脸识别1】从图片中检测人脸
[opencv人脸识别一]从图片中检测人脸 本系列主要讲述利用opencv实现人脸识别的相关知识,并给出实际代码.且循序渐进,由基础到复杂,从最基本的图片检测人脸到视频检测.识别人脸,再到较大型人脸数 ...
- OpenCV 人脸识别 源代码
请直接查看原文 OpenCV 人脸识别 源代码 https://hotdog29.com/?p=553 在 2019年7月6日 上张贴 由 hotdog发表回复 opencv 人脸识别 在本教程中,您 ...
- 基于python opencv人脸识别的员工考勤系统
WorkAttendanceSystem 一个基于opencv人脸识别的员工考勤系统,作者某双一流A类大学里的一流学生,写于2018/09/,python课设期间. 源代码详细解释请关注微信公众号: ...
- WPF编程--OpenCV人脸识别
目录 1. 环境 2. NuGet导入依赖 3. 创建WriteableBitmapHelper.cs类 4. 编辑MainWindow.xaml.cs 5. 编辑MainWindow.xaml 1. ...
最新文章
- ubuntu16.04 server unrar解压rar文件提示command not found和解压tar.bz2文件
- 【随笔】JVM核心:JVM运行和类加载
- docker进阶 一键安装wordpress
- 菜鸟也玩WebMatrix
- 【Git】git stash应用场景
- 阿里云开源的Blink,计算能力很疯狂:一眨眼,全部都算好!
- 网络请求以及网络请求下载图片的工具类 android开发java工具类
- sar —— Linux 上最为全面的系统性能分析工具之一
- phpstorm 配置自带webserver ,配置根目录
- axios拦截器_Axios源码解析 —— 一个小而美的HttpClient
- java se用哪个eclipse_javaSE----eclipse的安装与使用
- FIT2CLOUD获网宿科技战略投资 深度聚焦混合云管理价值交付
- java word 分页显示_Java 在Word中插入分页符、分节符
- 数据类型--Number类型
- 鹏博士总经理陆榴遭免职 董事称事发突然
- miss工作室官宣加盟新公司是真的吗
- 联想电脑怎么录屏?这3个方法,轻松解决
- querylist V4 图片下载
- 程序设计思维与实践 CSP-M4
- Visio用UML2.5模板包下载地址
热门文章
- 深度丨110亿美金还不够,阿里使用这种AI手段创造更多广告收入
- 顶级风投First Round Capital对创业者的30个建议
- 数据结构与算法笔记(八)—— 插入排序
- 爬虫学习笔记(十六)—— Selenium
- oracle linux内存推荐分配,浅析Oracle 的体系架构及内存分配机制
- Java 调用 Kotlin
- android view setx,Android的setX()和setY()表现不可思议
- Matlab图像形态学处理—开操作和闭操作
- fluent计算进出口的流量差
- fileupload.class.php,php文件上传类