教你一步一步用python在圖像上作物體檢測

最近正要作一我的臉識別的門禁系統,因此打算抽出一些時間來作一個系列專題,講解下我在系統中用到的一些技術來知足一下祖傳的好爲人師的願望。html

既然要識別人臉,那第一步固然要檢測出人臉的位置。java

恰好opencv提供了一些圖像處理和識別的基本方法,提供了C++、python、java的接口,我我的比較喜歡用python來編程,因此接下來在本文中都會提供用python寫的代碼。python

 

說一下編程的環境需求(Requirement):linux

  • 系統:windows / linux / macos算法

  • 解釋器:python3macos

  • 依賴庫:numpy >= 1.0、opencv-python 三、opencv-contrib-python 3(接下來的代碼都是基於python3和opencv3寫的,其餘版本可能會不支持,須要稍做修改)編程

     

python解釋器能夠在python官網( https://www.python.org/ )下載安裝包直接安裝,這裏不作贅述,下面來安裝必須的依賴庫,在命令行中輸入:windows

pip3 install numpy==1.14.5

pip3 install opencv-python==3.4.1.15 

pip3 install opencv-contrib-python==3.4.2.17 

 

爲了保證不出現版本不兼容問題,我把全部的庫都規定了版本api

關於IDE有不少選擇,比較出名的有Pycharm、Spyder、Eclipse+pydev、Eric,和科學計算有關的建議用Spyder:bash

 

 

它提供了一個相似於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%的正確率,可是大多數狀況下是能夠達到一個不錯的效果。

 

固然,這個級聯分類器並非只能夠檢測人臉,加載不一樣的模型,就能夠檢測不一樣的物體, 好比說喵臉:

 

 

今天就先到這裏,下次再詳細講解對檢測到的人臉進行人臉識別,並在圖上貼上姓名標籤,也就是對人臉進行分類。

 

 

個人微信公衆號二維碼

歡迎關注!

 

這是個人微信號二維碼,掃一掃能夠和我交流:

 

原文連接:https://mp.weixin.qq.com/s/-C5Uq_3O6GZk2KW0kL1GWA