Opencv3.4深度学习人脸检测(C++)

开发环境:Ubuntu14.04, Opencv3.4, Clion

CMakeLists.txt编写如下:

cmake_minimum_required(VERSION 3.10)
project(demo)
set(CMAKE_CXX_STANDARD 11)
find_package(OpenCV REQUIRED)
add_executable(demo main.cpp)
target_link_libraries(demo ${OpenCV_LIBS})

之前的opencv人脸检测使用的是Haar特征,效果一(la)般(ji),下面直接贴出源码

#include <iostream>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
CascadeClassifier faceCascade;
int main() {
/*
//图片人脸检测
    faceCascade.load("/home/zzr/opencv-3.4.4/data/haarcascades/haarcascade_frontalface_alt2.xml");//加载分类器
    Mat img = imread("/home/zzr/Desktop/me.jpg");
    Mat imgGray;
    vector<Rect> faces;
    if(img.empty())return 1;
    if(img.channels() ==3) {
        cvtColor(img, imgGray, CV_RGB2GRAY); // RGB转化为灰度
    }
    else {imgGray = img;} // 不转化
    faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));// 检测人脸
    if(faces.size()>0)
    {
        for(int i =0; i<faces.size(); i++)
        {
            rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 255, 0), 1, 8);    // 框出人脸
        }
    }
    imshow("FacesOfPrettyGirl", img); // 显示图片
    waitKey(0);
    return 0;
*/
//摄像头实时检测//
    faceCascade.load("/home/zzr/opencv-3.4.4/data/haarcascades/haarcascade_frontalface_alt2.xml");//加载分类器
    VideoCapture capture;
    capture.open(-1);// 打开摄像头
//      capture.open("video.avi");    // 打开视频
    if(!capture.isOpened())
    {
        cout << "open camera failed. " << endl;
        return -1;
    }
    Mat img, imgGray;
    vector<Rect> faces;
    while(1)
    {
        capture >> img;// 读取图像至img
        if(img.empty())continue;
        if(img.channels() == 3)cvtColor(img, imgGray, CV_RGB2GRAY);
        else{imgGray = img;}
        faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));// 检测人脸
        if(faces.size()>0)
        {
            for(int i =0; i<faces.size(); i++)
            {
                rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 255, 0), 1, 8);
            }
        }
        imshow("CamerFace", img); // 显示
        if(waitKey(1) != -1)break;// delay ms 等待按键退出
    }
    return 0;
}

上面的代码分别包括图片人脸检测和视频人脸检测,代码中的注释也比较清楚了,这边说明几点:

  1. 打开摄像头时capture.open(index), 我这边只能用-1;
  2. 关于waitKey(delay)函数的用法,delay代表需要等待多长时间,返回值是我们键盘操作的ASCALL码,如果键盘无操作则返回-1;

再看一下DNN model的源码

#include <iostream>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace cv::dnn;
using namespace std;
const size_t inWidth = 300;
const size_t inHeight = 300;
const double inScaleFactor = 1.0;
const Scalar meanVal(104.0, 177.0, 123.0);
int main()
{
    float min_confidence = 0.5;
    String modelConfiguration = "/home/zzr/opencv-3.4.4/samples/dnn/face_detector/deploy.prototxt";
    String modelBinary = "/home/zzr/opencv-3.4.4/samples/dnn/face_detector/res10_300x300_ssd_iter_140000_fp16.caffemodel";
    //! [Initialize network]
    Net net = readNetFromCaffe(modelConfiguration, modelBinary);
    //! [Initialize network]
    if (net.empty())
    {
        cerr << "Can't load network by using the following files: " << endl;
        cerr << "prototxt:   " << modelConfiguration << endl;
        cerr << "caffemodel: " << modelBinary << endl;
        cerr << "Models are available here:" << endl;
        cerr << "<OPENCV_SRC_DIR>/samples/dnn/face_detector" << endl;
        cerr << "or here:" << endl;
        cerr << "https://github.com/opencv/opencv/tree/master/samples/dnn/face_detector" << endl;
        exit(-1);
    }
    VideoCapture cap(-1);//must be -1
    if (!cap.isOpened())
    {
        cout << "Couldn't open camera : " << endl;
        return -1;
    }
    for (;;)//while(1)
    {
        Mat frame;
        cap >> frame; // get a new frame from camera/video or read image
        if (frame.empty())break;
        if (frame.channels() == 4)cvtColor(frame, frame, COLOR_BGRA2BGR);
        //! [Prepare blob]
        Mat inputBlob = blobFromImage(frame, inScaleFactor,
                                      Size(inWidth, inHeight),
                                      meanVal, false, false); //Convert Mat to batch of images
        //! [Set input blob]
        net.setInput(inputBlob, "data"); //set the network input
        //! [Make forward pass]
        Mat detection = net.forward("detection_out"); //compute output
        vector<double> layersTimings;
        double freq = getTickFrequency() / 1000;
        double time = net.getPerfProfile(layersTimings) / freq;
        Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());
        ostringstream ss;
        ss << "FPS: " << 1000 / time << " ; time: " << time << " ms";
        putText(frame, ss.str(), Point(20, 20), 0, 0.5, Scalar(0, 0, 255));
        float confidenceThreshold = min_confidence;
        for (int i = 0; i < detectionMat.rows; i++)
        {
            float confidence = detectionMat.at<float>(i, 2);
            if (confidence > confidenceThreshold)
            {

                auto xLeftBottom = static_cast<int>(detectionMat.at<float>(i, 3) * frame.cols);
                auto yLeftBottom = static_cast<int>(detectionMat.at<float>(i, 4) * frame.rows);
                auto xRightTop = static_cast<int>(detectionMat.at<float>(i, 5) * frame.cols);
                auto yRightTop = static_cast<int>(detectionMat.at<float>(i, 6) * frame.rows);
                Rect object(xLeftBottom, yLeftBottom,
                                       (xRightTop - xLeftBottom),
                                       (yRightTop - yLeftBottom));
                rectangle(frame, object, Scalar(0, 255, 0));
                ss.str("");
                ss << confidence;
                String conf(ss.str());
                String label = "Face: " + conf;
                int baseLine = 0;
                Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
                rectangle(frame, Rect(Point(xLeftBottom, yLeftBottom - labelSize.height),
                                      Size(labelSize.width, labelSize.height + baseLine)),
                          Scalar(255, 255, 255), CV_FILLED);
                putText(frame, label, Point(xLeftBottom, yLeftBottom),
                        FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0));
            }
        }
        cv::imshow("detections", frame);
        if (waitKey(1)!=-1) break;
    }
    return 0;
}

上面的代码就是利用SSD检测人脸,首先需要下载SSD的模型文件,模型位于${OPENCV_DIR}\samples\dnn\face_detector,里面有个download_weights.py,执行下就可以自动下载模型了。然后我们直接看结果,哇

!!!

参考:https://blog.csdn.net/minstyrain/article/details/78907425

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值