基于PCA算法的人脸识别,可以制作自己的样本来识别自己的脸部

优采云 发布时间: 2020-08-06 08:30

  当我刚刚学习OpenCV时,我对面部识别很感兴趣,并且感到能够识别自己的面部非常好. 经过一段时间的学习,实际上并不困难. 大多数在线面部识别是PCA算法. 这是一个相对较旧的算法. OpenCV附带了大多数功能,使用此算法学习起来更方便.

  让我们讨论从制作样本到训练样本,最后通过照相机识别您的脸部的整个过程.

  1. 图像采集和预处理

  为了识别指定的人,需要将识别出的人的照片制作成数据集,这是一种训练模型. 拍照的传统方法是使用手机拍照和拍照. 一个人需要20张具有不同角度和表情的照片. 为了实现几个人的训练模式,用手机拍照比较麻烦,效果也不佳. 最好通过计算机摄像机来实现. 通过查阅信息,我编写了一个小程序来使用OpenCV拍照,并预先处理了图片的灰度和中值滤波. 然后将图片缩小到指定的120 * 120尺寸,所拍摄的图片可以达到样本水平,节省了大量的二次处理.

  代码如下:

  #include

using namespace cv;

int main()

{

VideoCapture cap(0);

Mat frame;

int i=0;

while (1)

{

char key = waitKey(100);

cap >> frame;

imshow("frame", frame);

Mat out;

Mat out1;

Mat out2;

cvtColor(frame, out1, CV_BGR2GRAY);//灰度化

medianBlur(out1,out,7);//中值滤波

resize(out, out2, Size(120, 120));//尺寸缩减

imshow("out", out2);

string filename = format("D:\\pic\\pic%d.jpg", i);//存入文件路径

switch (key)

{

case'p': //按'P'拍照

i++;

imwrite(filename, out2);

imshow("photo", out2);

waitKey(500);

destroyWindow("photo");

break;

default:

break;

}

}

}

  以这种方式获得的照片已经过处理,可以用作样本. 效果如图所示:

  

  这样的初步样品已经准备好了.

  2.CSV文件生成

  编写面部模型的训练程序时,需要读取面部和与该面部相对应的标签. 直接在数据库中读取显然效率低下. 因此我们使用csv文件进行读取. csv文件收录两个方面,一个是每个图片的位置,另一个是与每个面孔相对应的标签,即每个人的人数. 这个at.txt文件是我们需要的csv文件. 如图所示:

  

  在图片中,前面显示的路径是图片的位置,后面的数字是与图片对应的人的标签. 如果将其用于学习,并且仅制作一组样本进行实验,则可以直接手动创建一个复制路径. 工作量并不大,可以由三个人在几分钟内完成. 如果您想做一个以上的工作,则可以使用OpenCV自己的脚本自动生成它(您可以在线搜索它,我在这里忘记了它),最后您可以获取收录路径和标签的csv文件.

  3. 培训模式

  已经准备好数据集和csv文件,然后可以训练模型. 首先,您需要首先提取以前的图片和标签,这时您需要使用at.txt. 使用csv文件读取图像和标签,主要使用stringstream和getline方法. Stringstream主要用于分割字符串并单独输出单个内容; getline从输入流中读取字符并将它们存储在指定的位置. 通过stringstream和getline两种方法,csv文件中的图像和标签分别存储在图像和标签的容器中.

  请注意,此处的at.txt文件的内容和CSV文件的内容需要放置在训练模型代码的文件夹中,否则,如果加载失败,则会报告错误.

  培训模型代码如下:

<p>#include

#include

#include

#include

#include

using namespace cv;

using namespace std;

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& images, vector& 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 = "at.txt";

// 2个容器来存放图像数据和对应的标签

vector images;

vector labels;

// 读取数据. 如果文件不合法就会出错

// 输入的文件名已经有了.

try

{

read_csv(fn_csv, images, labels);

}

catch (cv::Exception& e)

{

cerr > frame;

//建立用于存放人脸的向量容器

vector 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);

}

}

Mat face_test;

int predictPCA = 0;

if (face.rows >= 120)

{

resize(face, face_test, Size(92, 112));

}

//Mat face_test_gray;

//cvtColor(face_test, face_test_gray, CV_BGR2GRAY);

if (!face_test.empty())

{

//测试图像应该是灰度图

predictPCA = modelPCA->predict(face_test);

}

cout

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线