zoukankan      html  css  js  c++  java
  • opencv学习之路(41)、人脸识别

    一、人脸检测并采集个人图像

    //take_photo.cpp
    #include<opencv2/opencv.hpp>
    using namespace cv;
    using namespace std;
    
    void take_photo() {
        VideoCapture cap(0); //打开摄像头
        if (!cap.isOpened())
            return;
    
        //加载级联检测器
        CascadeClassifier cascade;
        cascade.load("F:/opencv3.2/Release_x64/etc/haarcascades/haarcascade_frontalface_alt_tree.xml");
    
        Mat frame;
        vector<Rect>faces;
        int count = 0;
        while (cap.read(frame))        //相当于cap >> frame
        {
            cascade.detectMultiScale(frame, faces, 1.1, 1, 0, Size(100, 100), Size(400, 400));//检测是否有人脸
            for (int i = 0; i < faces.size(); i++)
            {
                if (count % 10 == 0) {    //每10帧保存一次人脸图像
                    Mat dst;
                    resize(frame(faces[i]), dst, Size(92, 112));//设置人脸图像大小
                    cvtColor(dst, dst, COLOR_BGR2GRAY);//转为灰度图节省计算
                    imwrite(format("att_faces/s41/pic%d.jpg", count / 10), dst);
                }
                rectangle(frame, faces[i], Scalar(0, 255, 0));
            }
            imshow("video", frame);
    
            //按下任意键退出摄像头(waitkey在本系统环境下默认为255),或者是保存了20张人脸图片后,退出
            if (waitKey(50) != 255 || count / 10>20)
                break;
            count++;
        }
        cap.release();
        destroyAllWindows();//关闭所有窗口
    }

     运行程序,打开摄像头后会自动保存人脸图像,头不要晃动,表情变化即可,对于不合适的照片还需进行筛选。

     二、基于特征脸算法的人脸识别

    //face_recognition.cpp
    #include <opencv2/opencv.hpp>
    #include <opencv2/face.hpp>
    
    using namespace cv;
    using namespace cv::face;
    using namespace std;
    
    double face_recognition() {
        //读取文件,转换为数据流
        string filename = string("at.txt");
        ifstream file(filename.c_str(), ifstream::in);
        if (!file)
            cout << "error" << endl;
    
        string line, path, classlabel;
        vector<Mat>image;
        vector<int>labels;
        char separator = ';';
        while (getline(file, line))
        {
            stringstream liness(line);
            getline(liness, path, separator);
            getline(liness, classlabel);
            if (!path.empty() && !classlabel.empty())
            {
                //cout << "path:" << path<< endl;
                image.push_back(imread(path, 0));
                labels.push_back(atoi(classlabel.c_str()));
            }
        }
        if (image.size() < 1 || labels.size() < 1)
            cout << "invalid image path..." << endl;
    
        //最后一个人为测试样本
        Mat testSample = image[image.size() - 1];
        int testLabel = labels[labels.size() - 1];
        image.pop_back();
        labels.pop_back();
    
        //EigenFace算法的模型训练
        Ptr<BasicFaceRecognizer>model = createEigenFaceRecognizer();
        model->train(image, labels);
    
        //对样本进行识别
        int predictLabel = model->predict(testSample);
        cout << "actual label:" << testLabel << ",predict label:" << predictLabel << endl;
    
        //加载级联检测器
        CascadeClassifier cascade;
        cascade.load("haarcascade_frontalface_alt_tree.xml");//识别时用alt_tree分类器,宁可漏检也不误检
    
        //打开摄像头
        VideoCapture cap(0);
        if (!cap.isOpened())
            cout << "error...";
    
        Mat frame;
        vector<Rect>faces;
        int correct = 0, total = 0;
        while (cap.read(frame))        //相当于cap >> frame,读取摄像头的每一帧
        {
            cascade.detectMultiScale(frame, faces, 1.1, 1, 0, Size(80, 100), Size(380, 400));//检测是否有人脸
            for (int i = 0; i < faces.size(); i++)
            {
                Mat roi = frame(faces[i]);
                cvtColor(roi, roi, COLOR_BGR2GRAY);
                resize(roi, testSample, testSample.size());
                int label = model->predict(testSample);
                rectangle(frame, faces[i], Scalar(0, 255, 0));
                if (label == 41)
                {
                    putText(frame, "ZhangChunFu", faces[i].tl(), FONT_HERSHEY_COMPLEX, 1.0, Scalar(0, 0, 255));
                    correct++;
                }
                else
                    putText(frame, format("%d", label), faces[i].tl(), CV_FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255));
            }
            total++;
            imshow("人脸识别——MR.Zhang", frame);
            if (waitKey(50) == 27)
                break;
        }
    
        cap.release();
        destroyAllWindows();//关闭所有窗口
        waitKey(0);
    
        double rate = (1.0*correct) / total;
        return rate;//返回正确率
    }
    //main.cpp
    #include <opencv2/opencv.hpp>
    #include <opencv2/face.hpp>
    #include <iostream>
    
    using namespace cv;
    using namespace cv::face;
    using namespace std;
    
    void take_photo();
    double face_recognition();
    
    void main() {
        int flag;
        double rate;
        cout << "欢迎使用人脸识别系统(1代表录入人脸,2代表识别人脸),请输入您的选择:" << endl;
        cin >> flag;
        cout << "请稍等片刻……"<<endl;
        switch (flag)
        {
        case 1:take_photo();
            return;
        case 2:
            rate=face_recognition();
            break;
        default:
            break;
        }
        cout << "识别率:" << rate << endl;
        system("pause");
    
    }

  • 相关阅读:
    ionic文档
    Can't resolve all parameters for Storage: (?).
    cannot find module @ionicapp-scriptsinionic-app-scripts.js
    ionic 环境搭建
    学习文档记录
    js 文件引用传递参数
    No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
    js 去除左右空格
    sql 多行数据合并
    filter @Autowired nullPointer
  • 原文地址:https://www.cnblogs.com/little-monkey/p/8126619.html
Copyright © 2011-2022 走看看