使用OpenCV+DNN來實作人臉辨識

前言: 基於正在學習 Face detection with OpenCV and deep learning 為期17天的教材課程, 希望透過此平台紀錄一下第一天所學到的東西, 並透過額外網路搜尋整理所學到的知識。

DNN模組介紹:

在OpenCV3.3版本釋出中把DNN模組從擴充套件移入到了OpenCV的正式釋出模組中,目前DNN模組最早來自Tiny-dnn,可以載入預先訓練好的Caffe模型資料,OpenCV做了近一步擴充套件支援所有主流的深度學習框架訓練生成與匯出模型資料載入,常見的有如下:

  • Caffe
  • TensorFlow
  • Torch/PyTorch

OpenCV中DNN模組已經支援與測試過這些常見的網路模型

  • AlexNet
  • GoogLeNet v1 (also referred to as Inception-5h)
  • ResNet-34/50/…
  • SqueezeNet v1.1
  • VGG-based FCN (semantical segmentation network)
  • ENet (lightweight semantical segmentation network)
  • VGG-based SSD (object detection network)
  • MobileNet-based SSD (light-weight object detection network)

face_detector介紹:

當使用OpenCV提供的DNN模組以及載入預先訓練好的Caffee模型資料, 另外還需要兩份資料:

  1. The .prototxt file(s) which define the model architecture (i.e., the layers themselves)
  2. The .caffemodel file which contains the weights for the actual layers

當使用通過Caffee訓練的模型進行深度學習時, 這兩份文件都是不可少的! 前者是定義模型架構,主要是各layer的編排,後者則是包含各層layer權重設定的二進位檔案。

OpenCV的深度學習人臉辨識是基於Single Shot Detector(SSD)框架以及深度殘差網路(ResNet), 有興趣的朋友可以再自行深入了解ResNet模型。此篇主要介紹是OpenCV透過支援載入預先訓練好的Caffee模型, 實作出影像辨識。

可能這時候會有人問如果想要使用自己的數據來訓練模型要怎麼做, 那就要參考 how_to_train_face_detector

事前準備檔案:

  1. .prototxt : https://github.com/opencv/opencv/blob/master/samples/dnn/face_detector/deploy.prototxt
  2. .caffeemodel : https://github.com/sr6033/face-detection-with-OpenCV-and-DNN/blob/master/res10_300x300_ssd_iter_140000.caffemodel

Python程式碼介紹:

#載入需要的套件
import numpy as np
import argparse
import cv2

透過argparse命令列解析模組讀取參數設定

ap = argparse.ArgumentParser()ap.add_argument("-i", "--image", required=True,help="path to input image")ap.add_argument("-p", "--prototxt", required=True,help="path to Caffe 'deploy' prototxt file")ap.add_argument("-m", "--model", required=True,help="path to Caffe pre-trained model")ap.add_argument("-c", "--confidence", type=float, default=0.5,help="minimum probability to filter weak detections")args = vars(ap.parse_args())

待會執行時需要給予三種參數值

  • — image : The path to the input image.
  • — prototxt : The path to the Caffe prototxt file.
  • — model : The path to the pretrained Caffe model.

另一個可選擇的參數是 — confidence, 可以覆寫原本的預設值0.5

載入要使用的model並且從照片中產生blob, 網路上查了一下可以理解Blob為經二值化(Binary Thresholding)處理後的圖像色斑。

透過cv2.dnn.blobFromImage()函式對圖像進行預處理, 包含設定blob維度和使用正規化進行縮減值, 返回一個4通道的的blob用於神經網路輸入。

net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"])
image = cv2.imread(args["image"])
(h, w) = image.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0,(300, 300), (104.0, 177.0, 123.0))

接下來我們要應用人臉偵測, 將處理過的blob帶入到net網路模型中, forward()能取得跑完模型的結果, 方法為透過向前傳遞法, DNN就是把input透過超過一層的hidden layer產生計算結果能對應出output各個的機率值, 即所謂feedforwarding。

net.setInput(blob)
detections = net.forward()

forward()函式說明

Net_forward(self, blobs=None, start=None, end=None, **kwargs) method of caffe._caffe.Net instance

Forward pass: prepare inputs and run the net forward.

Parameters

— — — — —

1. blobs : list of blobs to return in addition to output blobs.

2. kwargs : Keys are input blob names and values are blob ndarrays.For formatting inputs for Caffe, see Net.preprocess().If None, input is taken from data layers.

3. start : optional name of layer at which to begin the forward pass

4. end : optional name of layer at which to finish the forward pass(inclusive)

Returns

— — — –

outs : {blob name: blob ndarray} dict.

再來就是針對剛剛得到的detections跑回圈:

for i in range(0, detections.shape[2]):

先提取與預測相關的置信度(即機率), 與一開始提到的 可選項的參數confidence做比較, 預設是找出比0.5置信度大的點, 劃出方格來標示出圖像中最有可能的人臉位置,並標上對應的機率為多少, 程式碼如下:

confidence = detections[0, 0, i, 2]if confidence > args["confidence"]:box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
text = "{:.2f}%".format(confidence * 100)
y = startY - 10 if startY - 10 > 10 else startY + 10cv2.rectangle(image, (startX, startY), (endX, endY),
(0, 0, 255), 2)cv2.putText(image, text, (startX, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)

最後結束迴圈, 印出含有跑完DNN認為是人臉的圖像以及機率。

cv2.imshow("Output", image)
cv2.waitKey(0)

另外影像辨識人臉也跟這個程式碼雷同, 主要是image改成frame的形式做處理。

實際測試:

總結:

之前有參賽過Kaggle競賽, 對於訓練模型來說會有一些概念, 所以再看到DNN時不至於來的陌生, 雖然也才剛接觸OpenCV, 但它提供的DNN模組結合已經訓練過的模型來做人臉辨識, 馬上就能體驗到人臉辨識的功能, 甚至找了幾張人臉比例較特殊的圖像都還有不錯的辨識結果, 後來還修改了confidence的參數值調大調小的確得到了不同的結果呢!

接下來如果有時間會想要深入了解模型架構, 自己定義layers以及權重, 從中學習整體設計全貌以及看能用什麼方式提升效能。

初次使用Medium平台撰寫技術分享的心得, 希望讀者能夠給予改進地方, 以及如果有說明的不清楚還請多多包涵。

參考網址:

https://github.com/opencv/opencv/tree/master/samples/dnn/face_detector

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章