深度學習:口罩檢測器
由於疫情關係,出門都要帶著口罩,為了確保進出的人都能戴口罩,因此衍伸出了這個主題。雖然說物件偵測之前有做過,但開始做之前還是看了不少國外的範例,其實大家方法都差不多,如果是使用深度學習,感覺就差資料庫的不同而已,所以最後決定就使用 OpenCV + 深度學習的辨識模型來實作看看。
這其實是去年做的一個小專題,趁著還有印象來記錄一下😄😄
程式架構
整個架構分成兩個部分,先用 OpenCV 的人臉辨識來找到臉的位置,再利用 CNN 來辨識這張臉是否有帶口罩。CNN 的部分會用 Keras 來訓練分類模型,將會分成戴口罩和沒戴口罩的類別,而訓練用的影像資料將會從別人 Open Source 的資料庫來訓練,然後再加入一些自己的影像。
程式實現
OpenCV 的人臉偵測模型
最新的 OpenCV 可以使用 DNN 的模組來做人臉偵測,只要使用 cv2.dnn.readNet 來引入模型極權重就可以使用,這邊考慮到速度,使用 SSD 模型來偵測人臉位置。
(1) 事前需要準備兩個檔案來讀取人臉偵測模型,分別是模型的配置檔案及權重:
- deploy.prototxt
- res10_300x300_ssd_iter_140000.caffemodel
(2) 另一個重點是使用 cv2.dnn.blobFromImage 來進行神經網路模型的輸入。它的工作機制,可以當成預處理影像資料,好讓深度神經網絡獲得更準確的預測。通常在深度學習和圖像分類中,這些預處理通常包括:
- 均值減法 (Mean subtraction)
- 縮放 (Scaling)
- 裁切 (Crop) ……等等
在 blobFromImage 中,我們可以設定以下參數:
- image: 輸入影像。
- scalefactor: 各通道數值的縮放比例。
- size: 輸出圖像的尺寸 (W,H)。
- mean: 各通道減去的值,以降低光照的影響。
- swapRB: 交換RB通道,預設 False。 (cv2.imread讀取的是彩圖是bgr通道)。
- crop: 圖像裁剪,預設 False。當設為 True 時,先按比例縮放,然後從中心裁剪成 size 尺寸。
- ddepth: 輸出的圖像深度,可選 CV_32F 或者 CV_8U。
以上完成之後就可以用下面兩行,進行資料輸入及預測結果:
- faceNet.setInput(blob)
- faceNet.forward()
而 faceNet.forward 的輸出,就是最後預測結果,接下來就能從裡面取出人臉的ROI影像,然後丟到下一格檢測模型中。
口罩檢測模型
這個部分則是使用 Keras 來訓練分類模型,這邊我是過自己都神經網路訓練,也有使用 MobileV2 來做轉移學習,可能資料太少,自己建的模型效果不是很好。模型輸出分成兩類,一類是有戴口罩,另一類是沒戴口罩,不過網路上的資料庫的口罩是合成上去的,應該要用實際的資料會更好,所以網路上的大神提供以外,也將我自己的圖片也加入訓練,來提高測試時的準確度。
程式碼: https://github.com/jacky10001/Face-Mask-Detection
結語
其實感覺這程式還有很多優化空間,再加上使用兩個深度學習的模型其實有點太過於龐大,放在樹梅派裡其實幀率不太夠,找時間再來重新用影像處理做這個項目看看。