zoukankan      html  css  js  c++  java
  • 人脸识别-<转>

    人脸检测库libfacedetection介绍

    libfacedetection是于仕琪老师放到GitHub上的二进制库,没有源码,它的License是MIT,可以商用。目前只提供了windows 32和64位的release动态库,主页为https://github.com/ShiqiYu/libfacedetection,采用的算法好像是Multi-BlockLBP,提供了四套接口,分别为frontal、frontal_surveillance、multiview、multiview_reinforce,其中multiview_reinforce效果最好,速度比其它稍慢,四套接口的参数类型完全一致,可以根据需要对参数min_neighbors和min_object_width进行调整。

    新建一个控制台工程,用来测试libfacedetection,测试代码如下:

    #include <iostream>  
    #include <string>  
    #include <vector>  
    #include <facedetect-dll.h>  
    #include <opencv2/opencv.hpp>  
      
    int main()  
    {  
        std::vector<std::string> images{ "1.jpg", "2.jpg", "3.jpg", "4.jpeg", "5.jpeg", "6.jpg", "7.jpg", "8.jpg", "9.jpg", "10.jpg",  
            "11.jpeg", "12.jpg", "13.jpeg", "14.jpg", "15.jpeg", "16.jpg", "17.jpg", "18.jpg", "19.jpg", "20.jpg" };  
        std::vector<int> count_faces{1, 2, 6, 0, 1, 1, 1, 2, 1, 1,  
            1, 1, 1, 1, 1, 1, 1, 0, 8, 2};  
      
        std::string path_images{ "E:/GitCode/Face_Test/testdata/" };  
      
        if (images.size() != count_faces.size()) {  
            fprintf(stderr, "their size that images and count_faces are mismatch
    ");  
            return -1;  
        }  
      
        typedef int* (*detect_face)(unsigned char * gray_image_data, int width, int height, int step,  
            float scale, int min_neighbors, int min_object_width, int max_object_width);  
      
        detect_face detect_methods[]{  
            &facedetect_frontal,  
            &facedetect_multiview,  
            &facedetect_multiview_reinforce,  
            &facedetect_frontal_surveillance  
        };  
      
        std::string detect_type[4] {"face frontal", "face multiview", "face multiview reinforce", "face surveillance"};  
      
        for (int method = 0; method < 4; method++) {  
            detect_face detect = detect_methods[method];  
            fprintf(stderr, "detect type: %s
    ", detect_type[method].c_str());  
      
            for (int i = 0; i < images.size(); i++) {  
                cv::Mat src_ = cv::imread(path_images + images[i], 1);  
                if (src_.empty()) {  
                    fprintf(stderr, "read image error: %s
    ", images[i].c_str());  
                    return -1;  
                }  
      
                cv::Mat src;  
                cv::cvtColor(src_, src, CV_BGR2GRAY);  
      
                int* results = nullptr;  
                results = detect(src.data, src.cols, src.rows, src.step, 1.2f, 2, 10, 0);  
                std::string save_result = path_images + std::to_string(method) + "_" + images[i];  
                //fprintf(stderr, "save result: %s
    ", save_result.c_str());  
      
                for (int faces = 0; faces < (results ? *results : 0); faces++) {  
                    short* p = ((short*)(results + 1)) + 6 * faces;  
                    int x = p[0];  
                    int y = p[1];  
                    int w = p[2];  
                    int h = p[3];  
                    int neighbors = p[4];  
                    int angle = p[5];  
      
                    fprintf(stderr, "image_name: %s, faces_num: %d, face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d
    ",  
                        images[i].c_str(), *results, x, y, w, h, neighbors, angle);  
      
                    cv::rectangle(src_, cv::Rect(x, y, w, h), cv::Scalar(0, 255, 0), 2);  
                }  
      
                cv::imwrite(save_result, src_);  
            }  
        }  
      
        int width = 200;  
        int height = 200;  
        cv::Mat dst(height * 5, width * 4, CV_8UC3);  
        for (int i = 0; i < images.size(); i++) {  
            std::string input_image = path_images + "2_" + images[i];  
            cv::Mat src = cv::imread(input_image, 1);  
            if (src.empty()) {  
                fprintf(stderr, "read image error: %s
    ", images[i].c_str());  
                return -1;  
            }  
      
            cv::resize(src, src, cv::Size(width, height), 0, 0, 4);  
            int x = (i * width) % (width * 4);  
            int y = (i / 4) * height;  
            cv::Mat part = dst(cv::Rect(x, y, width, height));  
            src.copyTo(part);  
        }  
        std::string output_image = path_images + "result.png";  
        cv::imwrite(output_image, dst);  
      
        fprintf(stderr, "ok
    ");  
        return 0;  
    }  

    从网上找了20张图像,验证此库的检测率,下图是采用multiview_reinforce接口的检测结果:

    GitHubhttps://github.com/fengbingchun/Face_Test

    原文地址:http://blog.csdn.net/fengbingchun/article/details/52964163

    ==========================================================================

    Opencv与dlib联合进行人脸关键点检测与识别

    前言

    依赖库:opencv 2.4.9 /dlib 19.0/libfacedetection 
    本篇不记录如何配置,重点在算法实现上。使用libfacedetection实现人脸区域检测,联合dlib标记人脸特征点,最后使用opencv的FaceRecognizer实现人脸识别。

    准备工作

    1、配置好Opencv2.4.9。(Opencv3.1需要另外下载一个包才有FaceRecognizer) 
    2、配置好dlib 19.0(版本其实没有多大关系) 
    3、配置好ShiQi.Yu的人脸检测库

    思想

    训练模块:人脸检测——>获取人脸区域的点坐标——>人脸关键点标记——>人脸对正——>归一化处理——>保存图片——>手动筛选图片——>训练样本——>得到train.xml 
    识别模块:读取train.xml——>循环(人脸检测——>获取人脸区域的点坐标——>人脸关键点标记——>人脸对正——>归一化处理——>送入model->predict——>预测出结果——>putText在方框上写出名字)

    结果

    识别速度:0.15~0.25秒,Release平台。 
    识别精度:还可以,基本不会识别错,样本没有选择需要识别的东西哦。 
    使用了一段中国好声音的视频做识别。 
    这里写图片描述 
    这里写图片描述 
    这里写图片描述 
    当然,这里用的是Fisherface算法,主要还是样本不多,已经可以搞定了。

    代码

    ReadCSV.h

    #include <opencv.hpp>
    #include <iostream>
    #include <fstream>
    using namespace cv;
    using namespace std;
    static void read_csv(const string& filename, cv::vector<Mat>& images, cv::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()));
            }
        }
    }

    FaceRotate.h

    #include <dlib/image_processing/frontal_face_detector.h>
    #include <dlib/image_processing/render_face_detections.h>
    #include <dlib/image_processing.h>
    #include <dlib/gui_widgets.h>
    #include <dlib/image_io.h>
    #include<dlib/opencv/cv_image.h>
    #include <dlib/opencv.h>
    
    using namespace dlib;
    
    frontal_face_detector detector = get_frontal_face_detector();
    shape_predictor sp;//Already get

    FaceRecognition.cpp

    #include <FaceDetect.h>
    #include <ReadCSV.h>
    const int namenumber = 4;//测试的人脸数量
    const string textname[namenumber] = { "Hariem", "Miss.Na", "Mr.Wang", "Jay.Chou" };//做一个储存人脸名字的数组
    
    
    Ptr<FaceRecognizer>  GetTrainModel(string fn_csv)//输入CSV文件的路径名
    {
        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);
        }
        Ptr<FaceRecognizer> model = createEigenFaceRecognizer(80);//创建人脸识别类 可修改 LBPHFace、EigenFace、FisherFace
        model->train(images, labels);
        return model;
    }
    
    int main()
    {
        Dlib_Predefine();//加载dlib的文件
        Ptr<FaceRecognizer> model = GetTrainModel("face.csv");//获得模型
        VideoCapture cap("好声音.mp4");
        Mat frame,gray;
        while (true)
        {
            cap >> frame;
            if (!frame.empty())
            {
                gray = FaceDetect(frame);
                if (!gray.empty())
                putText(frame, textname[model->predict(gray)], Point(50, 50), FONT_HERSHEY_DUPLEX, 3, Scalar(230, 255, 0), 2);//model->predict(frame) = predictLabel 名字写在 1 1
                imshow("Face Recogniton", frame);
                waitKey(1);
            }
            else{ cout << "The Video's end." <<endl; break; }
        }
    
    }

    FaceDetect.cpp

    用了掩码。

    #include <FaceDetect.h>
    #include <FaceRotate.h>
    void Dlib_Predefine()
    {
        deserialize("shape_predictor_68_face_landmarks.dat") >> sp;//读入标记点文件
    }
    
    cv::Mat FaceToOne(cv::Mat source)//归一化处理函数
    {
    
        cv::equalizeHist(source, source);//直方图均衡
        cv::resize(source, source, cv::Size(92, 112));//裁剪
        cv::Mat Mask = cv::imread("mask.jpg", 0);
        cv::Mat changedMask;
        source.copyTo(changedMask, Mask);
        return changedMask;
    }
    
    Mat FaceDetect(Mat frame)//脸是否存在
    {
        Mat gray, error;
        cvtColor(frame, gray, CV_BGR2GRAY);
        int * pResults = NULL;
        pResults = facedetect_frontal_tmp((unsigned char*)(gray.ptr(0)), gray.cols, gray.rows, gray.step, 1.2f, 5, 24);
        int peopleNUM = (pResults ? *pResults : 0);
    
        for (int i = 0; i < peopleNUM; i++)//代表有几张人脸(pResults ? *pResults : 0)
        {
            short * p = ((short*)(pResults + 1)) + 6 * i;
            Rect opencvRect(p[0], p[1], p[2], p[3]);
            //gray = gray(opencvRect);
            cv::rectangle(frame, opencvRect, Scalar(230, 255, 0));
            dlib::rectangle dlibRect((long)opencvRect.tl().x, (long)opencvRect.tl().y, (long)opencvRect.br().x - 1, (long)opencvRect.br().y - 1);
            //人脸对齐技术提高了准确率
            dlib::full_object_detection shape = sp(dlib::cv_image<uchar>(gray), dlibRect);//标记点
            std::vector<full_object_detection> shapes;
            shapes.push_back(shape);//把点保存在了shape中
            dlib::array<array2d<rgb_pixel>>  face_chips;
            extract_image_chips(dlib::cv_image<uchar>(gray), get_face_chip_details(shapes), face_chips);
            Mat pic = toMat(face_chips[0]);
            cvtColor(pic, pic, CV_BGR2GRAY);
            return FaceToOne(pic);
        }
        return error;
    }

    FaceDetect.h

    #include <opencv.hpp>
    #include "facedetect-dll.h"
    
    using namespace cv;
    using namespace std;
    
    Mat FaceDetect(Mat frame);
    void Dlib_Predefine();//dlib 预定义的函数

    FaceRotate.h

    #include <dlib/image_processing/frontal_face_detector.h>
    #include <dlib/image_processing/render_face_detections.h>
    #include <dlib/image_processing.h>
    #include <dlib/gui_widgets.h>
    #include <dlib/image_io.h>
    #include<dlib/opencv/cv_image.h>
    #include <dlib/opencv.h>
    
    using namespace dlib;
    
    frontal_face_detector detector = get_frontal_face_detector();
    shape_predictor sp;//Already get

    Mask图片: 
    这里写图片描述

    有几个说明

    已经全部更正。

    原文地址:http://blog.csdn.net/mr_curry/article/details/51994497

    ==========================================================

    如何快糙好猛的使用libfacedetection库【最新版】

    前言

    最近已经很少看CSDN了。这一年多准备考研,基本上怕是不会再怎么上了。以前有一个http://blog.csdn.net/mr_curry/article/details/51804072 如何快糙好猛的使用Shiqi.Yu老师的公开人脸检测库(附源码)的BLOG,因为于老师的库已经更新了,所以重新写一下吧。 
    PS:这个库越来越强了,已经可以做人脸关键点检测了。关键点检测可以用于矫正人脸,再也不要用慢的要死的dlib啦~~

    配置

    五张图带你解决问题:(X64,Debug) 
    这里写图片描述
    这里写图片描述
    这里写图片描述

    然后你需要把opencv的属性表也引进来: 
    这里写图片描述

    两个方法,加系统变量或者放到和exe同一个文件夹下。加了系统变量后重启一次才生效,所以这里就直接放咯
    这里写图片描述

    代码

    我们直接用FDDB上评测效果最好的函数:facedetect_multiview_reinforce 

    #include <opencv.hpp>
    #include <facedetect-dll.h>
    using namespace cv;
    using namespace std;
    
    //define the buffer size. Do not change the size!
    #define DETECT_BUFFER_SIZE 0x20000
    
    int main()
    {
        int * pResults = NULL;
        //pBuffer is used in the detection functions.
        //If you call functions in multiple threads, please create one buffer for each thread!
        unsigned char * pBuffer = (unsigned char *)malloc(DETECT_BUFFER_SIZE);
        if (!pBuffer)
        {
            fprintf(stderr, "Can not alloc buffer.
    ");
            return -1;
        }
        Mat src = imread("img.jpg");
        Mat gray;
        cvtColor(src, gray, CV_BGR2GRAY);
        int doLandmark = 1;// do landmark detection
        pResults = facedetect_multiview_reinforce(pBuffer, (unsigned char*)(gray.ptr(0)), gray.cols, gray.rows, (int)gray.step,
            1.2f, 2, 48, 0, doLandmark);
        //print the detection results
        for (int i = 0; i < (pResults ? *pResults : 0); i++)
        {
            short * p = ((short*)(pResults + 1)) + 142 * i;
            rectangle(src, Rect(p[0], p[1], p[2], p[3]), Scalar(0, 255, 0), 2);
            if (doLandmark)
            {
                for (int j = 0; j < 68; j++)
                    circle(src, Point((int)p[6 + 2 * j], (int)p[6 + 2 * j + 1]), 1, Scalar(0, 0, 255),2);
            }
        }
        imshow("Show", src);
        waitKey(0);
    }

    效果还是很赞: 
    这里写图片描述

    视频流中的人脸检测代码就是用VideoCapture解析为Mat然后循环检测啊:

    #include <opencv.hpp>
    #include <facedetect-dll.h>
    using namespace cv;
    using namespace std;
    
    //define the buffer size. Do not change the size!
    #define DETECT_BUFFER_SIZE 0x20000
    
    int main()
    {
        int * pResults = NULL;
        //pBuffer is used in the detection functions.
        //If you call functions in multiple threads, please create one buffer for each thread!
        unsigned char * pBuffer = (unsigned char *)malloc(DETECT_BUFFER_SIZE);
        if (!pBuffer)
        {
            fprintf(stderr, "Can not alloc buffer.
    ");
            return -1;
        }
        int doLandmark = 1;// do landmark detection
        VideoCapture cap(0);
        if (!cap.isOpened()){
            cout << "Please check your USB camera's interface num." << endl;
            return 0;
        }
        Mat src;
        while (true)
        {
            cap >> src;
            if (!src.empty()){
                Mat gray;
                cvtColor(src, gray, CV_BGR2GRAY);
                pResults = facedetect_multiview_reinforce(pBuffer, (unsigned char*)(gray.ptr(0)), gray.cols, gray.rows, (int)gray.step,
                    1.2f, 2, 48, 0, 1);
                for (int i = 0; i < (pResults ? *pResults : 0); i++)
                {
                    short * p = ((short*)(pResults + 1)) + 142 * i;
                    rectangle(src, Rect(p[0], p[1], p[2], p[3]), Scalar(0, 255, 0), 2);
                    if (doLandmark)
                    {
                        for (int j = 0; j < 68; j++)
                            circle(src, Point((int)p[6 + 2 * j], (int)p[6 + 2 * j + 1]), 1, Scalar(0, 0, 255), 2);
                    }
                }
                imshow("Show", src);
                waitKey(1);
            }
    
        }
    }

    原文地址:http://blog.csdn.net/Mr_Curry/article/details/65945071

  • 相关阅读:
    fileupload直接获得
    ajax分页
    jquery.cookie.js
    DataTable分页
    C#字串与Unicode互相转换方法
    Linq测试
    滚动条加载数据
    创建.PDF文件【1】
    小问题【6】
    小问题【4】
  • 原文地址:https://www.cnblogs.com/wainiwann/p/8135538.html
Copyright © 2011-2022 走看看