教你一步一步用python在影象上做物體檢測
最近正要做一個人臉識別的門禁系統,所以打算抽出一些時間來做一個系列專題,講解下我在系統中用到的一些技術來滿足一下祖傳的好為人師的願望。
既然要識別人臉,那第一步當然要檢測出人臉的位置。
剛好opencv提供了一些影象處理和識別的基本方法,提供了C++、python、java的介面,我個人比較喜歡用python來程式設計,所以接下來在本文中都會提供用python寫的程式碼。
說一下程式設計的環境需求(Requirement):
-
系統:windows / linux / macos
-
直譯器:python3
-
依賴庫:numpy >= 1.0、opencv-python 3、opencv-contrib-python 3(接下來的程式碼都是基於python3和opencv3寫的,其他版本可能會不支援,需要稍作修改)
python直譯器可以在python官網( https://www.python.org/ )下載安裝包直接安裝,這裡不做贅述,下面來安裝必須的依賴庫,在命令列中輸入:
pip3 install numpy==1.14.5
pip3 install opencv-python==3.4.1.15
pip3 install opencv-contrib-python==3.4.2.17
為了保證不出現版本不相容問題,我把所有的庫都規定了版本
關於IDE有很多選擇,比較出名的有Pycharm、Spyder、Eclipse+pydev、Eric,和科學計算有關的建議用Spyder:
它提供了一個類似於MATLAB的變數顯示選單,可以清楚地看到建立的每一個變數的型別、數值、大小等,對於除錯非常方便:
可以看到每個圖片變數的矩陣原始值。
好了,基本的程式設計和執行環境已經搭建完了,下面開始設計程式碼,基本的思路是使用 Paul Viola和 Michael Jones 的論文《Rapid Object Detection using a Boosted Cascade of Simple Features》中的演算法,opencv很好的實現了這個演算法,並把它封裝在了級聯分類器中,所以接下來寫程式碼的步驟就變成了:載入級聯分類器人臉模型 -> 開啟攝像頭 -> 獲取圖片 -> 圖片灰度化 -> 人臉檢測 -> 畫出矩形框 -> 影象顯示 。
這裡用的是Haar特徵來描述人臉,它反映了影象的灰度變化情況。
下面開始撰寫程式碼:
1. 引入opencv模組
import cv2
2. 載入級聯分類器模型:
faceCascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
在opencv的‘\sources\data\haarcascades’目錄下可以找到這個官方訓練好的普適性模型,效果還過得去,如果想要更加的準確或者識別其他物體,可以自己用正負樣本去訓練(記得把模型放在和程式碼相同的目錄下)
3. 開啟攝像頭
cap = cv2.VideoCapture(0)
4. 獲取圖片
ret, image = cap.read()
5. 影象灰度化(降低運算強度)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
6. 人臉檢測
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5, minSize=(30, 30),)
detectMultiScale函式的第一個引數是灰度影象。
第二個引數是scaleFactor,不同人距離鏡頭不一樣,有的臉比較大,有的小,scaleFactor用來對此進行補償。
分類器使用滑動視窗來檢測物體, minSize是每個視窗的大小,minNeighbors會定義其周圍有多少物體。
detectMultiScale返回了一個numpy array:faces,檢測出幾個人臉列表的長度即為多少,faces中每一行中的元素分別表示檢出的人臉在圖中的(座標x、座標y、寬度、高度)
7. 在原先的彩圖上畫出包圍框(綠色框,邊框寬度為2)
for (x, y, width, height) in faces:
cv2.rectangle(image, (x, y), (x + width, y + height), (0, 255, 0), 2)
8. 顯示圖片
cv2.imshow("Face",image)
cv2.waitKey(0)
看,它很完美的檢測出了我的臉在圖片中的位置:
再來個大合照:
需要把從攝像頭獲取資料改為從圖片讀取資料:
image = cv2.imread(image_path)
Look, 並沒有出現種族歧視的現象。
當然有時候也會出現一些誤識別和漏識別的情況:
這個時候如果期望達到更好的識別效果,可能需要去自己訓練模型(https://coding-robin.de/2013/07/22/train-your-own-opencv-haar-classifier.html)或者做一些圖片的預處理使圖片更容易識別、調節detectMultiScal函式中的各個引數來達到期望的效果。
Warning:由於級聯分類器使用的是機器學習演算法,所以不能期望它達到100%的正確率,但是大多數情況下是可以達到一個不錯的效果。
當然,這個級聯分類器並不是只可以檢測人臉,載入不同的模型,就可以檢測不同的物體, 比如說喵臉:
今天就先到這裡,下次再詳細講解對檢測到的人臉進行人臉識別,並在圖上貼上姓名標籤,也就是對人臉進行分類。
我的微信公眾號二維碼:
歡迎關注!
這是我的微訊號二維碼,掃一掃可以和我交流: