人臉識別-<轉>

人臉檢測庫libfacedetection介紹ios

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進行調整。git

新建一個控制檯工程,用來測試libfacedetection,測試代碼以下:github

#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\n");  
        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\n", 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\n", 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\n", 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\n",  
                    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\n", 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\n");  
    return 0;  
}  

從網上找了20張圖像,驗證此庫的檢測率,下圖是採用multiview_reinforce接口的檢測結果:算法

 

GitHubhttps://github.com/fengbingchun/Face_Testwindows

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

==========================================================================iview

Opencv與dlib聯合進行人臉關鍵點檢測與識別

前言

依賴庫:opencv 2.4.9 /dlib 19.0/libfacedetection 
本篇不記錄如何配置,重點在算法實現上。使用libfacedetection實現人臉區域檢測,聯合dlib標記人臉特徵點,最後使用opencv的FaceRecognizer實現人臉識別。tcp

準備工做

一、配置好Opencv2.4.9。(Opencv3.1須要另外下載一個包纔有FaceRecognizer) 
二、配置好dlib 19.0(版本其實沒有多大關係) 
三、配置好ShiQi.Yu的人臉檢測庫ide

思想

訓練模塊:人臉檢測——>獲取人臉區域的點座標——>人臉關鍵點標記——>人臉對正——>歸一化處理——>保存圖片——>手動篩選圖片——>訓練樣本——>獲得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.\n");
        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.\n");
        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

相關文章
相關標籤/搜索