前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV+OpenVINO实现人脸Landmarks实时检测

OpenCV+OpenVINO实现人脸Landmarks实时检测

作者头像
OpenCV学堂
发布2020-04-14 16:43:42
1.7K0
发布2020-04-14 16:43:42
举报

微信公众号:OpenCV学堂 关注获取更多计算机视觉与深度学习知识

缘由

自从OpenCV3.3版本引入深度神经网络(DNN)模块之后,OpenCV对DNN模块支持最好的表现之一就是开始支持基于深度学习人脸检测,OpenCV本身提供了两个模型分别是基于Caffe与Tensorflow的,Caffe版本的模型是半精度16位的,tensorflow版本的模型是8位量化的。同时OpenCV通过与OpenVINO IE模型集成实现了底层硬件对对象检测、图像分割、图像分类等常见模型加速推理支持。OpenVINO框架本身提供直接快速开发应用原型的模型库,对很多常见视觉任务都可以做到快速演示支持。说起人脸的Lankmarks提取,最早的OpenCV跟DLib支持的方式都是基于AAM算法实现的68个人脸特征点的拟合模型,另外OpenCV中支持landmark的人脸检测会先加载一个很大的模型文件,然后速度感人,觉得还有很大的改进空间。好处是OpenCV自己提供了一个训练工具,可以自己训练模型。常见的MTCNN同时实现了人脸检测跟landmarks检测,但是只支持5点检测。而OpenVINO自带的Landmark检测模型基于自定义的卷积神经网络实现,取35个人脸各部位关键点。

模型文件

人脸检测模型

使用OpenCV DNN模块人脸检测的tensorflow量化8位模型

代码语言:javascript
复制
opencv_face_detector_uint8.pb权重文件
opencv_face_detector.pbtxt配置文件

OpenCV3.3以上版本支持

Landmarks检测

代码语言:javascript
复制
模型名称:facial-landmarks-35-adas-0002

支持35点分布表示出左眼、右眼、鼻子、嘴巴、左侧眉毛、右侧眉毛、人脸轮廓。模型的输入格式为:

代码语言:javascript
复制
BCHW = [1x3x60x60]

模型的输出数据为:[1x70]大小的浮点数组、对应到35个点x、y的坐标。

输出层名称:align_fc3

程序演示

首先加载模型文件

代码语言:javascript
复制
// 加载LANDMARK
Net mkNet = readNetFromModelOptimizer(landmark_xml, landmark_bin);
mkNet.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
mkNet.setPreferableTarget(DNN_TARGET_CPU);

// 加载网络
Net net = cv::dnn::readNetFromTensorflow(tensorflowWeightFile, tensorflowConfigFile);
net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
net.setPreferableTarget(DNN_TARGET_CPU);

使用网络实现人脸检测与landmark检测

首先读取视频的每一帧,检测人脸,得到的人脸区域转换位blob对象之后,再调用landmark检测模型forward方法得到输出结果,实现的代码如下:

代码语言:javascript
复制
Mat frame;
while (true) {
    bool ret = cap.read(frame);
    if (!ret) {
        break;
    }
    // flip(frame, frame, 1);
    cv::Mat inputBlob = cv::dnn::blobFromImage(frame, 1.0, cv::Size(300, 300),
        Scalar(104.0, 177.0, 123.0), false, false);
    net.setInput(inputBlob, "data");
    cv::Mat detection = net.forward("detection_out");
    cv::Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.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) * w);
            int y1 = static_cast<int>(detectionMat.at<float>(i, 4) * h);
            int x2 = static_cast<int>(detectionMat.at<float>(i, 5) * w);
            int y2 = static_cast<int>(detectionMat.at<float>(i, 6) * h);
            Mat roi = frame(Range(y1, y2), Range(x1, x2));
            Mat blob = blobFromImage(roi, 1.0, Size(60, 60), Scalar(), false, false);
            mkNet.setInput(blob);
            Mat landmark_data = mkNet.forward();
            // printf("rows: %d \n, cols : %d \n", landmark_data.rows, landmark_data.cols);
            for (int i = 0; i < landmark_data.cols; i += 2) {
                float x = landmark_data.at<float>(0, i)*roi.cols+x1;
                float y = landmark_data.at<float>(0, i + 1)*roi.rows+y1;
                // mkList.push_back(Point(x, y));
                circle(frame, Point(x, y), 2, Scalar(0, 0, 255), 2, 8, 0);
            }
            cv::rectangle(frame, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 255, 0), 2, 8);
        }
    }
    imshow("Face-Detection Demo", frame);
    char c = waitKey(1);
    if (c == 27) {
        break;
    }
}

运行结果如下:

至于速度,我只能告诉你很实时,我是i7 CPU。

想尝试下载与使用OpenVINO直接从下面链接即可开始:

代码语言:javascript
复制
https://software.intel.com/en-us/openvino-toolkit/choose-download?innovator=CONT-0026250
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV学堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档