首先進行圖片的讀取,使用opencv的haar鼻子特征分類器,如果檢測到鼻子,則證明沒有戴口罩。如果檢測到鼻子,接著使用opencv的haar眼睛特征分類器,如果沒有檢測到眼睛,則結(jié)束。如果檢測到眼睛,則把RGB顏色空間轉(zhuǎn)為HSV顏色空間。進行口罩區(qū)域的檢測??谡謪^(qū)域檢測流程是首先把距離坐標原點的較近的橫坐標作為口罩區(qū)域開始橫坐標,離坐標原點較遠的橫坐標作為口罩區(qū)域結(jié)束橫坐標。離坐標原點較遠的縱坐標作為口罩區(qū)域開始縱坐標,離坐標原點較遠的縱坐標與眼睛高度2倍的和作為口罩區(qū)域結(jié)束縱坐標。在此敘述的可能不是很清楚,可以見圖3-2,
"""
# File : mask_check.py
# Time :2021/6/10 15:02
# Author :Meng
# version :python 3.6
# Description:
"""
import cv2 # 導(dǎo)入opencv
import time # 導(dǎo)入time
"""實現(xiàn)鼻子檢測"""
def nose_dection(img):
img = cv2.GaussianBlur(img,(5,5),0)#高斯濾波
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 將圖片轉(zhuǎn)化成灰度
nose_cascade = cv2.CascadeClassifier("haarcascade_mcs_nose.xml")
nose_cascade.load("data/haarcascades/haarcascade_mcs_nose.xml") # 一定要告訴編譯器文件所在的具體位置
'''此文件是opencv的haar鼻子特征分類器'''
noses = nose_cascade.detectMultiScale(gray, 1.3, 5) # 鼻子檢測
for(x,y,w,h) in noses:
cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) # 畫框標識臉部
flag = 0 # 檢測到鼻子的標志位,如果監(jiān)測到鼻子,則判斷未帶口罩
if len(noses)>0:
flag = 1
return img,flag
""""實現(xiàn)眼睛檢測"""
def eye_dection(img):
img = cv2.GaussianBlur(img,(5,5),0)#高斯濾波
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 將圖片轉(zhuǎn)化成灰度
eyes_cascade = cv2.CascadeClassifier("haarcascade_eye_tree_eyeglasses.xml")
eyes_cascade.load("data/haarcascades/haarcascade_eye_tree_eyeglasses.xml") # 一定要告訴編譯器文件所在的具體位置
'''此文件是opencv的haar眼鏡特征分類器'''
eyes = eyes_cascade.detectMultiScale(gray, 1.3, 5) # 眼睛檢測
for (x,y,w,h) in eyes:
frame = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) # 畫框標識眼部
print("x y w h is",(x,y,w,h))
# frame = cv2.rectangle(img, (x, y+h), (x + 3*w, y + 3*h), (255, 0, 0), 2) # 畫框標識眼部
return img,eyes
def empty(a):
pass
def main():
image = cv2.imread("images/backgound.png") # 讀取背景照片
cv2.imshow('skin', image) # 展示
cv2.createTrackbar("Hmin", "skin", 0, 90, empty) # 創(chuàng)建bar
cv2.createTrackbar("Hmax", "skin", 25, 90, empty)
capture = cv2.VideoCapture(0) # 打開攝像頭,其中0為自帶攝像頭,
while True:
ref,img=capture.read() # 打開攝像頭
# img = cv2.imread("./images/005.jpg") # 讀取一張圖片
img_hsv = img
image_nose,flag_nose = nose_dection(img) # 進行口罩檢測,返回檢測之后的圖形以及標志位
if flag_nose == 1: # 當檢測到鼻子的時候,判斷未戴口罩
frame = cv2.putText(image_nose, "NO MASK", (10, 30), cv2.FONT_HERSHEY_COMPLEX, 0.9,(0, 0, 255), 1) # 在圖片上寫字
cv2.imshow('img', image_nose) # 展示圖片
if flag_nose == 0: # 未檢測鼻子,進行眼睛檢測
img_eye,eyes = eye_dection(img) # 進行眼睛檢測,返回檢測之后的圖形以及標志位
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 將圖片轉(zhuǎn)化成HSV格式
H, S, V = cv2.split(hsv) #
minH = cv2.getTrackbarPos("Hmin", 'skin') # 獲取bar
maxH = cv2.getTrackbarPos("Hmax", 'skin')
if minH > maxH:
maxH = minH
thresh_h = cv2.inRange(H, minH, maxH) # 提取人體膚色區(qū)域
if len(eyes) > 1: # 判斷是否檢測到兩個眼睛,其中eyes[0]為左眼坐標
# 口罩區(qū)域的提取
mask_x_begin = min(eyes[0][0],eyes[1][0]) # 把左眼的x坐標作為口罩區(qū)域起始x坐標
mask_x_end = max(eyes[0][0],eyes[1][0]) + eyes[list([eyes[0][0], eyes[1][0]]).index(max(list([eyes[0][0], eyes[1][0]])))][2] # 把右眼x坐標 + 右眼寬度作為口罩區(qū)域x的終止坐標
mask_y_begin = max(eyes[0][1] + eyes[0][3],eyes[1][1] + eyes[1][3]) + 20 # 把眼睛高度最大的作為口罩區(qū)域起始y坐標
if mask_y_begin > img_eye.shape[1]: # 判斷是否出界
mask_y_begin = img_eye.shape[1]
mask_y_end = max(eyes[0][1] + 3 * eyes[0][3],eyes[1][1] + 3 * eyes[1][3]) + 20 # 同理
if mask_y_end > img_eye.shape[1]:
mask_y_end = img_eye.shape[1]
frame = cv2.rectangle(img_eye, (mask_x_begin, mask_y_begin), (mask_x_end, mask_y_end), (255, 0, 0), 2) # 畫口罩區(qū)域的框
total_mask_pixel = 0
total_face_pixel = 0
# 遍歷二值圖,為0則total_mask_pixel+1,否則total_face_pixel+1
for i in range(mask_x_begin,mask_x_end):
for j in range(mask_y_begin,mask_y_end):
if thresh_h[i,j] == 0:
total_mask_pixel += 1
else:
total_face_pixel += 1
print("total_mask_pixel",total_mask_pixel)
print("total_face_pixel", total_face_pixel)
if total_mask_pixel > total_face_pixel:
frame = cv2.putText(img_eye, "HAVE MASK", (mask_x_begin, mask_y_begin - 10),cv2.FONT_HERSHEY_COMPLEX, 0.9, (0, 0, 255), 1) # 繪制
if total_mask_pixel total_face_pixel:
frame = cv2.putText(img_eye, "NO MASK", (mask_x_begin, mask_y_begin - 10), cv2.FONT_HERSHEY_COMPLEX,0.9, (0, 0, 255), 1) # 繪制
cv2.imshow("skin", thresh_h) # 顯示膚色圖
cv2.imshow("img", img_eye) # 顯示膚色圖
# cv2.imwrite('005_result.jpg',img_eye) 保存圖片
c = cv2.waitKey(10)
if c==27:
break
capture.release() #
cv2.destroyAllWindows() # 關(guān)閉所有窗口
if __name__ == '__main__':
main()
本實驗使用了opencv-python進行了人臉口罩檢測。進行鼻子、眼睛檢測使用的時opencv自帶的.xml文件。從結(jié)果來看,這種方法是可行的。是可以應(yīng)用在地鐵站、火車站出入口進行人臉口罩檢測的。
本實驗也有一定局限性,例如圖片中有兩個人、眼睛被遮擋等特殊情況。如果感興趣可以自己訓(xùn)練.xml文件。當然,也可以使用基于深度學(xué)習(xí)的目標檢測模型例如R-CNN系列、YOLO系列、SSD等進行模型的訓(xùn)練。
到此這篇關(guān)于python基于Opencv實現(xiàn)人臉口罩檢測的文章就介紹到這了,更多相關(guān)Opencv 人臉口罩檢測內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!