文章目錄
- 基于Python通過OpenCV實作的口罩識別系統操作篇
- 前言
- 一、級聯分類器
- 二、使用步驟
- 1.引入庫2.引入級聯分類器3.物件識別方式
- 三、畫出識別物件
- 代碼操作方式測驗效果
- 總代碼展示:
很多人學習python,不知道從何學起,
很多人學習python,掌握了基本語法過后,不知道在哪里尋找案例上手,
很多已經做案例的人,卻不知道如何去學習更加高深的知識,
那么針對這三類人,我給大家提供一個好的學習平臺,免費領取視頻教程,電子書籍,以及課程的源代碼!
QQ群:961562169
前言
理論思路介紹篇,可以查看往日文章,
專案實作環境:
基于Python 3.8.1版本
opencv-python 4.2.0.34版本
需要自己下載OpenCV的庫檔案,添加其中的分類器
一、級聯分類器
首先要引入相應的級聯分類器
本專案一共使用了三個級聯分類器:
人臉面部識別樹:haarcascade_frontalface_alt2.xml
人臉面部鼻子識別樹:haarcascade_mcs_nose.xml
口罩檢測識別訓練樹:cascade.xml(這個訓練的級聯分類器是第三方制作檔案,非OpenCV原廠訓練檔案)
二、使用步驟
1.引入庫
import cv2.cv2 as cv import time import numpy as np import pygame import threading
以上的相應庫函式,通過python的pip可以進行添加,添加OpenCV庫的時候容易出現多個bug,建議參考以前的文章OpenCV的安裝,
2.引入級聯分類器
引入分類器時候,注意使用分類器是要將其引入的地址填寫正確,
face_cascade = cv.CascadeClassifier('D:/OPENCV/opencv/build/etc/haarcascades/haarcascade_frontalface_alt2.xml')#人臉面部識別
eye_cascade = cv.CascadeClassifier('D:/OPENCV/opencv/build/etc/haarcascades/haarcascade_eye_tree_eyeglasses.xml')#面部眼鏡識別
nose_cascade = cv.CascadeClassifier('D:/OPENCV/opencv/build/etc/haarcascades/haarcascade_mcs_nose.xml')#人臉面部鼻子識別
mask_detector = cv.CascadeClassifier("D:/OPENCV/opencv/build/etc/haarcascades/cascade.xml")#人臉佩戴口罩識別
3.物件識別方式
可以看到一共有8個引數,
1.img(必需)
這個不用多解釋,顯然是要輸入的影像,影像可以是彩色也可以是灰度的,
2.foundLocations
存取檢測到的目標位置
3.hitThreshold (可選)
opencv documents的解釋是特征到SVM超平面的距離的閾值(Threshold for the distance between features and SVM classifying plane)
所以說這個引數可能是控制HOG特征與SVM最優超平面間的最大距離,當距離小于閾值時則判定為目標,
4.winStride(可選)
HoG檢測視窗移動時的步長(水平及豎直),
winStride和scale都是比較重要的引數,需要合理的設定,一個合適引數能夠大大提升檢測精確度,同時也不會使檢測時間太長,
5.padding(可選)
在原圖外圍添加像素,作者在原文中提到,適當的pad可以提高檢測的準確率(可能pad后能檢測到邊角的目標?)
常見的pad size 有(8, 8), (16, 16), (24, 24), (32, 32).
6.scale(可選)
圖是一個影像金字塔,也就是影像的多尺度表示,每層影像都被縮小尺寸并用gaussian平滑,
scale引數可以具體控制金字塔的層數,引數越小,層數越多,檢測時間也長, 一下分別是1.01 1.5 1.03 時檢測到的目標, 通常scale在1.01-1.5這個區間
7.finalThreshold(可選)
這個引數不太清楚,有人說是為了優化最后的bounding box
8.useMeanShiftGrouping(可選)
bool 型別,決定是否應用meanshift 來消除重疊,
default為false,通常也設為false,另行應用non-maxima supperssion效果更好,
實際代碼
ret, frame = cameraCapture.read()#首先是將攝像頭轉化的輸出轉化為一幀一幀的影像
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)將影像轉化為灰度影像,減少運算量
faces = face_cascade.detectMultiScale(gray, 1.2, 10)#運用比對函式1.2為每次以1.2倍移動比對,10為識別次數為10次便認為是我們需要的影像,
masks = mask_detector.detectMultiScale(gray, 1.03, 5)#
noses = nose_cascade.detectMultiScale(gray, 1.2, 10)#
對比引數需要按照實際情況進行測驗和調整,有時候將對比次數調整的過高將會導致程式的運算量過大,雖然準確無誤,但是又會忽略許多的殘缺實際物件,比如上圖中的小孩子,就會被忽略,
三、畫出識別物件
代碼操作方式
代碼如下(示例):
ret, frame = cameraCapture.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.2, 10)# 1.02
masks = mask_detector.detectMultiScale(gray, 1.03, 5)# 1.01
noses = nose_cascade.detectMultiScale(gray, 1.2, 10)# 1.05
for (x, y, w, h) in faces:
cv.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv.putText(frame, "no_mask", (x, y), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
n = n + 1
no_mask = no_mask+1
for (mx, my, mw, mh) in masks:
cv.rectangle(frame, (mx, my), (mx + mw, my + mh), (0, 255, 0), 2)
cv.putText(frame, "have_mask", (mx, my), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
n = n + 1
have_mask = have_mask + 1
for (nx, ny, nw, nh) in noses:
cv.rectangle(frame, (nx, ny), (nx + nw, ny + nh), (10, 10, 255), 2)
cv.putText(frame, "no_mask", (nx, ny), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
# n = 1
no_mask = 1
通過識別和比對,輸出的值將通過for回圈輸出,并且使用OpenCV畫出矩形框,并得出是否佩戴口罩,
測驗效果
以下為測驗結果:
在影像中通過分類器比對,找到了匹配的資料后,將所得到的資料進行畫框,并且輸出出來了,以上為全臉未帶口罩,識別出了鼻子和人臉,使用紅色框圖進行表示,
以上為佩戴口罩狀態,將會識別佩戴口罩的人臉,并且用綠色框圖表示,
在佩戴口罩不完全時,主要以識別口鼻等關鍵部位,進行判斷是否佩戴了口罩,
在對比效率的情況下,測驗結果為,未佩戴眼鏡時,匹配準確率和效率都較為高,主要原因分析:由于引入的級聯分類器的訓練樣本多為未佩戴眼鏡的,所以在配戴眼鏡時,會對其產生一定的干擾,
總代碼展示:
專案一:只含有口罩識別,未添加語音提醒,
import cv2.cv2 as cv
import time
import pygame
def detect():
n = 0
have_mask = 0
no_mask = 0
face_cascade = cv.CascadeClassifier('D:/OPENCV/opencv/build/etc/haarcascades/haarcascade_frontalface_alt2.xml')
eye_cascade = cv.CascadeClassifier('D:/OPENCV/opencv/build/etc/haarcascades/haarcascade_eye_tree_eyeglasses.xml')
nose_cascade = cv.CascadeClassifier('D:/OPENCV/opencv/build/etc/haarcascades/haarcascade_mcs_nose.xml')
mask_detector = cv.CascadeClassifier("D:/OPENCV/opencv/build/etc/haarcascades/cascade.xml")
cameraCapture = cv.VideoCapture(0, cv.CAP_DSHOW)# cv.CAP_DSHOW
while True:
start = time.time()
ret, frame = cameraCapture.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.2, 10)# 1.02
masks = mask_detector.detectMultiScale(gray, 1.03, 5)# 1.01
noses = nose_cascade.detectMultiScale(gray, 1.2, 10)# 1.05
for (x, y, w, h) in faces:
cv.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv.putText(frame, "no_mask", (x, y), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
n = 1
have_mask = 1
# roi_gray = gray[y:y+h, x:x+w]
# img = frame[y:y+h, x:x+w]
# eyes = eye_cascade.detectMultiScale(roi_gray, 1.03, 8, 0)
# for (ex, ey, ew, eh) in eyes:
# cv.rectangle(img, (ex, ey), (ex+ew, ey+eh), (0, 255, 255), 2)
for (mx, my, mw, mh) in masks:
cv.rectangle(frame, (mx, my), (mx + mw, my + mh), (0, 255, 0), 2)
cv.putText(frame, "have_mask", (mx, my), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
n = 1
no_mask = 1
for (nx, ny, nw, nh) in noses:
cv.rectangle(frame, (nx, ny), (nx + nw, ny + nh), (10, 10, 255), 2)
cv.putText(frame, "no_mask", (nx, ny), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
n = 1
no_mask = 1
c = cv.waitKey(50)
if c == 27:
break
# 計算幀率
end = time.time() # 結束時間
fps = 1 / (end - start) # 幀率
image = cv.putText(frame, "fps:{:.3f}".format(fps), (550, 15), cv.FONT_HERSHEY_COMPLEX, 0.5, (0, 255, 0), 1) # 繪制
image2 = cv.putText(image, f"Number of people tested:{n}", (400, 40), cv.FONT_HERSHEY_COMPLEX, 0.5, (0, 255, 255), 1)
image3 = cv.putText(image2, f'Number of people wearing masks:{have_mask}', (325, 60), cv.FONT_HERSHEY_COMPLEX, 0.5, (0, 255, 0), 1)
image4 = cv.putText(image3, f'Number of people not wearing masks:{no_mask}', (290, 80), cv.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 1)
cv.imshow('camera', image4)
cameraCapture.release()
cv.destroyAllWindows()
if __name__=='__main__':
detect()
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/159500.html
標籤:其他
上一篇:Python多執行緒
