OpenCV+OpenVINO實現人臉Landmarks實時檢測

原因

自從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我的臉各部位關鍵點。html

OpenCV+OpenVINO實現人臉Landmarks實時檢測

人臉檢測模型

使用OpenCV DNN模塊人臉檢測的tensorflow量化8位模型算法

  • opencv_face_detector_uint8.pb權重文件
  • opencv_face_detector.pbtxt配置文件
    OpenCV3.3以上版本支持

Landmarks檢測

模型名稱:facial-landmarks-35-adas-0002
支持35點分佈表示出左眼、右眼、鼻子、嘴巴、左側眉毛、右側眉毛、人臉輪廓。模型的輸入格式爲:數組

  • BCHW = [1x3x60x60]
    模型的輸出數據爲:[1x70]大小的浮點數組、對應到35個點x、y的座標。
    輸出層名稱:align_fc3

程序演示

首先加載模型文件網絡

// 加載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方法獲得輸出結果,實現的代碼以下:框架

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;
    }
}

運行結果以下:
OpenCV+OpenVINO實現人臉Landmarks實時檢測ide

至於速度,我只能告訴你很實時,我是i7 CPU。工具

想嘗試下載與使用OpenVINO直接從下面連接便可開始:
https://software.intel.com/en-us/openvino-toolkit/choose-download?innovator=C學習

學習OpenVINO開發技術看這裏
OpenVINO計算機視覺模型加速ui

相關文章
相關標籤/搜索