ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

OpenCV-人脸识别

2022-07-18 17:31:42  阅读:181  来源: 互联网

标签:gray 人脸识别 detectionMat int auto frame cap OpenCV


1 CascadeClassifier 级联分类器人脸识别

有两种:haar级联和lbp级联,我用brew安装的,级联文件在/opt/homebrew/Cellar/opencv/4.5.5_2/share/opencv4/haarcascades里面,haar级联文件大小是900kb左右,lbp级联文件大小是50kb左右。
检测前需要将图像转化成灰度图,并做直方图均衡化处理。

lbp的文件大小、识别速度和效果都要好于haar。

总的来说,人脸检测效果很一般,人脸不动时检测框会闪烁,人脸稍有偏转或遮挡就检测不到。

int myFaceDetect(int argc, char** argv) {
    double w = 0, h = 0, fps = 24;
    Mat frame;
    Mat gray;
    Mat res;
    VideoCapture cap;
    
    if (!cap.open(0)) {
        return 0;
    }
    w = cap.get(CAP_PROP_FRAME_WIDTH);
    h = cap.get(CAP_PROP_FRAME_HEIGHT);
    
    printf("cap w: %f, h: %f\n", w, h);
    
    namedWindow("cam");
    while(true) {
        auto tick = getTickCount();
//        cap >> frame;
        cap.read(frame);
        if (frame.empty()) {
            break;
        }
        flip(frame, frame, 1);
        cvtColor(frame, gray, COLOR_BGRA2GRAY);
        equalizeHist(gray, gray);
        
//        auto ccPath = "/opt/homebrew/Cellar/opencv/4.5.5_2/share/opencv4/haarcascades/haarcascade_frontalface_extended.xml";
        auto ccPath = "/opt/homebrew/Cellar/opencv/4.5.5_2/share/opencv4/lbpcascades/lbpcascade_frontalface_improved.xml";
        CascadeClassifier cc;
        if (!cc.load(ccPath)) {
            cout << "load CascadeClassifier failed" << endl;
            return -1;
        }
        vector<Rect> faces;
        cc.detectMultiScale(gray, faces);
        for (int i = 0; i < faces.size(); i++) {
            rectangle(frame, faces[i], Scalar(0, 0, 255));
        }
        imshow("cam", frame);
        auto time = (getTickCount() - tick) / getTickFrequency();
        printf("handleTime: %f\n", time);
        
        if (waitKey(1000 / fps) == ' ') {
            break;
        }
    }
    destroyAllWindows();
    return 0;
}

2 DNN 深度神经网络人脸识别

需要下载神经网络模型描述文件,模型大小为2.7Mb,描述文件大小为35kb

OpenCV的dnn支持caffe和TensorFlow两种模型,我这里用的是TensorFlow的模型。

检测直接用原始图像就行。

人脸检测效果非常好,人脸偏转或者遮挡一半仍能检测到。缺点是计算时间长一点,在移动端会明显一点。

int myDnnFaceDetect(int argc, char** argv) {
    double w = 0, h = 0, fps = 24;
    Mat frame;
    Mat gray;
    Mat res;
    VideoCapture cap;
    
    if (!cap.open(0)) {
        return 0;
    }
    w = cap.get(CAP_PROP_FRAME_WIDTH);
    h = cap.get(CAP_PROP_FRAME_HEIGHT);
    
    printf("cap w: %f, h: %f\n", w, h);
    
    auto pb_path = "/Users/chenrongchao/Downloads/face_detector-main/opencv_face_detector_uint8.pb";
    auto pbtext_path = "/Users/chenrongchao/Downloads/face_detector-main/opencv_face_detector.pbtxt";
    dnn::Net net = dnn::readNetFromTensorflow(pb_path, pbtext_path);
    
    namedWindow("cam");
    while(true) {
        auto tick = getTickCount();
//        cap >> frame;
        cap.read(frame);
        if (frame.empty()) {
            break;
        }
        flip(frame, frame, 1);
//        cvtColor(frame, gray, COLOR_BGRA2GRAY);
        
        auto blob = dnn::blobFromImage(frame, 1.0, Size2i(300, 300), Scalar(104,177,123),false,false);
        net.setInput(blob);
        auto probs = net.forward();
        Mat detectionMat(probs.size[2], probs.size[3], CV_32F, probs.ptr<float>());
        //解析结果
        for (int i = 0; i < detectionMat.rows; i++) {
            float confidence = detectionMat.at<float>(i, 2);
            if (confidence > 0.5) { //提取矩形四个角的坐标
                int x1 = static_cast<int>(detectionMat.at<float>(i, 3)*frame.cols);
                int y1 = static_cast<int>(detectionMat.at<float>(i, 4)*frame.rows);
                int x2 = static_cast<int>(detectionMat.at<float>(i, 5)*frame.cols);
                int y2 = static_cast<int>(detectionMat.at<float>(i, 6)*frame.rows);
                Rect box(x1, y1, x2 - x1, y2 - y1); //红色矩形框
                rectangle(frame, box, Scalar(0, 0, 255), 4, 8, 0); //标记人脸
            }
        }
        imshow("cam", frame);
        auto time = (getTickCount() - tick) / getTickFrequency();
        printf("handleTime: %f\n", time);
        
        if (waitKey(1000 / fps) == ' ') {
            break;
        }
    }
    destroyAllWindows();
    return 0;
}

标签:gray,人脸识别,detectionMat,int,auto,frame,cap,OpenCV
来源: https://www.cnblogs.com/rome753/p/16491282.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有