(八)OpenCV人脸识别_07_实时人脸识别

Kefira ·
更新时间:2024-11-13
· 998 次阅读

摄像头与人脸数据采集
VideoCapture类使用
使用HAAR 级联检测器实现人脸检测
对检测的人脸数据写入文件保存
删除错误数据与数据对齐
采集数据注意点 数据训练与测试
基于EigenFace算法实现数据训练与测试 实时人脸识别
检测人脸
识别人脸
实时显示人脸识别结果 整体流程:
人脸数据采集与处理->人脸数据训练与测试->实时人脸检测->人脸识别->显示结果/继续读取下一帧->选择终止->结束 Tips:
训练与检测的图像必须大小一致,类型为灰度
VideoCatpture类使用
HAAR人脸检测
数据采集通过眼睛标定实现数据一致 #include #include #include using namespace std; using namespace cv; using namespace cv::face; String Face_fileName = "haarcascade_frontalface_alt.xml";//opencv自带训练好的人脸识别Haar级联器 //String Face_fileName = "lbpcascade_frontalface.xml";//opencv自带训练好的人脸识别LBP级联器 CascadeClassifier face_cascade;//Haar人脸检测级联分类器 int main(int argc, char** argv) { String filename = string("face_image.txt");//标签Label_Text文件 //从硬盘到内存 ifstream file(filename.c_str(), ifstream::in);////c_str()函数可用可不用,无需返回一个标准C类型的字符串 if (!file)//打开标签文件失败 { cout << "could not load label_file" << endl; return -1; } string line, path, classlabel; vector images;//存放图像数据 vector labels;//存放图像标签 char separator = ';';//分号 while (getline(file, line)) //getline(cin,inputLine)//cin 是正在读取的输入流,而 inputLine 是接收输入字符串的 string 变量的名称 { stringstream liness(line);//这里采用stringstream主要作用是做字符串的分割 getline(liness, path, separator);//遇到分号就结束 getline(liness, classlabel);//继续从分号后面开始,遇到换行结束 if (!path.empty() && !classlabel.empty()) { images.push_back(imread(path,0));//imread(path,0)//0不能去 labels.push_back(atoi(classlabel.c_str()));//atoi字符串转换成整型数 } } if (images.size() <= 1 || labels.size() <= 1)//如果没有读到足够多的图片 { cout << "读取图片数据失败..." << endl; } int height = images[0].rows; //得到第一张图片的高度,在下面对图像变形得到他们原始大小时需要 int width = images[0].cols; cout << "读取的图片高度为:" << height << endl << "读取的图片宽度为:" << width << endl; //从数据集 中移除最后一张图片,用于做测试,需要根据自己的需要进行修改 Mat testSample = images[images.size() - 1];//获取最后一张照片 int testLabel = labels[labels.size() - 1];//获取最后一个标签 images.pop_back();//移除最后一张图片 labels.pop_back();//移除最后一个标签 /* 特征脸Eigenfaces 图像表示的问题是他的高维问题。 二维灰度图像p*q大小,是一个m=q*p维的向量空间,所以一个100*100像素大小的图像就是10,000维的图像空间。 但是不是所有的维数空间对我们来说都有用?我们可以做一个决定,如果数据有任何差异,我们可以通过寻找主元来知道主要信息。 主成分分析(Principal Component Analysis,PCA)是把一些可能相关的变量转换成一个更小的不相关的子集。 一个高维数据集经常被相关变量表示,因此只有一些的维上数据才是有意义的,包含最多的信息。 PCA方法寻找数据中拥有最大方差的方向,被称为主成分。 */ //创建一个特征脸模型用于人脸识别 //通过txt文件读取的图像和标签 训练它 //这里是一个完整的PCA变换 Ptr model = EigenFaceRecognizer::create(); model->train(images, labels); //人脸识别 //判断是否成功读取级联器 if (!face_cascade.load(Face_fileName)) { cout << "face_cascade error" << endl; return -1; }; //打开内置摄像头视频流 VideoCapture capture(0); Mat frame;//用来接capture Mat frame_gray; vector faces;//人脸区域 vector eyes;//人眼区域 while (capture.read(frame)) { cvtColor(frame, frame_gray, COLOR_BGR2GRAY);//转换为灰度图 equalizeHist(frame_gray, frame_gray);//直方图均衡化 face_cascade.detectMultiScale(frame_gray, faces, 1.2, 3, 0, Size(30, 30));//利用detectMultiScale搜索图像 for (size_t i = 0; i predict(testSample); putText(frame, format(Face_label == 10 ? "Handsome boy" : "Who're you?"), faces[i].tl(), FONT_HERSHEY_SIMPLEX, 1.5, Scalar(0, 0, 255), 2, 8); } imshow("人脸识别", frame); char c = waitKey(30); if (c == 27) { break; } } waitKey(0); return 0; }

输出结果:
成功检测人脸,并在人脸处绘制黄色圆;
当识别到标签10的人脸时,会出现红色字"Handsome boy";否则出现"Who’re you?"


作者:丶小早



opencv opencv人脸识别

需要 登录 后方可回复, 如果你还没有账号请 注册新账号