python基于Opencv實(shí)現(xiàn)人臉口罩檢測(cè)
一、開發(fā)環(huán)境
python 3.6.6
opencv-python 4.5.1
二、設(shè)計(jì)要求
1、使用opencv-python對(duì)人臉口罩進(jìn)行檢測(cè)
三、設(shè)計(jì)原理
設(shè)計(jì)流程圖如圖3-1所示,
圖3-1 口罩檢測(cè)流程圖
首先進(jìn)行圖片的讀取,使用opencv的haar鼻子特征分類器,如果檢測(cè)到鼻子,則證明沒有戴口罩。如果檢測(cè)到鼻子,接著使用opencv的haar眼睛特征分類器,如果沒有檢測(cè)到眼睛,則結(jié)束。如果檢測(cè)到眼睛,則把RGB顏色空間轉(zhuǎn)為HSV顏色空間。進(jìn)行口罩區(qū)域的檢測(cè)??谡謪^(qū)域檢測(cè)流程是首先把距離坐標(biāo)原點(diǎn)的較近的橫坐標(biāo)作為口罩區(qū)域開始橫坐標(biāo),離坐標(biāo)原點(diǎn)較遠(yuǎn)的橫坐標(biāo)作為口罩區(qū)域結(jié)束橫坐標(biāo)。離坐標(biāo)原點(diǎn)較遠(yuǎn)的縱坐標(biāo)作為口罩區(qū)域開始縱坐標(biāo),離坐標(biāo)原點(diǎn)較遠(yuǎn)的縱坐標(biāo)與眼睛高度2倍的和作為口罩區(qū)域結(jié)束縱坐標(biāo)。在此敘述的可能不是很清楚,可以見圖3-2,
圖3-2 口罩區(qū)域檢測(cè)圖
最后,知道口罩區(qū)域時(shí),只需對(duì)像素點(diǎn)進(jìn)行判斷就可以判斷出是否佩戴口罩。
四、程序代碼
""" # 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 """實(shí)現(xiàn)鼻子檢測(cè)""" 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) # 鼻子檢測(cè) for(x,y,w,h) in noses: cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) # 畫框標(biāo)識(shí)臉部 flag = 0 # 檢測(cè)到鼻子的標(biāo)志位,如果監(jiān)測(cè)到鼻子,則判斷未帶口罩 if len(noses)>0: flag = 1 return img,flag """"實(shí)現(xiàn)眼睛檢測(cè)""" 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) # 眼睛檢測(cè) for (x,y,w,h) in eyes: frame = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) # 畫框標(biāo)識(shí)眼部 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) # 畫框標(biāo)識(shí)眼部 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) # 進(jìn)行口罩檢測(cè),返回檢測(cè)之后的圖形以及標(biāo)志位 if flag_nose == 1: # 當(dāng)檢測(cè)到鼻子的時(shí)候,判斷未戴口罩 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: # 未檢測(cè)鼻子,進(jìn)行眼睛檢測(cè) img_eye,eyes = eye_dection(img) # 進(jìn)行眼睛檢測(cè),返回檢測(cè)之后的圖形以及標(biāo)志位 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: # 判斷是否檢測(cè)到兩個(gè)眼睛,其中eyes[0]為左眼坐標(biāo) # 口罩區(qū)域的提取 mask_x_begin = min(eyes[0][0],eyes[1][0]) # 把左眼的x坐標(biāo)作為口罩區(qū)域起始x坐標(biāo) 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坐標(biāo) + 右眼寬度作為口罩區(qū)域x的終止坐標(biāo) mask_y_begin = max(eyes[0][1] + eyes[0][3],eyes[1][1] + eyes[1][3]) + 20 # 把眼睛高度最大的作為口罩區(qū)域起始y坐標(biāo) 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()
五、結(jié)果展示
檢測(cè)結(jié)果如下:
圖5-1 HSV轉(zhuǎn)換結(jié)果圖
圖5-2 口罩檢測(cè)結(jié)果圖
圖5-3 口罩檢測(cè)結(jié)果圖(竟然把耳朵誤判為鼻子)
六、結(jié)論
本實(shí)驗(yàn)使用了opencv-python進(jìn)行了人臉口罩檢測(cè)。進(jìn)行鼻子、眼睛檢測(cè)使用的時(shí)opencv自帶的.xml文件。從結(jié)果來看,這種方法是可行的。是可以應(yīng)用在地鐵站、火車站出入口進(jìn)行人臉口罩檢測(cè)的。
本實(shí)驗(yàn)也有一定局限性,例如圖片中有兩個(gè)人、眼睛被遮擋等特殊情況。如果感興趣可以自己訓(xùn)練.xml文件。當(dāng)然,也可以使用基于深度學(xué)習(xí)的目標(biāo)檢測(cè)模型例如R-CNN系列、YOLO系列、SSD等進(jìn)行模型的訓(xùn)練。
到此這篇關(guān)于python基于Opencv實(shí)現(xiàn)人臉口罩檢測(cè)的文章就介紹到這了,更多相關(guān)Opencv 人臉口罩檢測(cè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 人臉檢測(cè)實(shí)戰(zhàn)終極之OpenCV+Python實(shí)現(xiàn)人臉對(duì)齊
- Python OpenCV利用筆記本攝像頭實(shí)現(xiàn)人臉檢測(cè)
- python opencv人臉檢測(cè)提取及保存方法
- python版opencv攝像頭人臉實(shí)時(shí)檢測(cè)方法
- Python3.6.0+opencv3.3.0人臉檢測(cè)示例
- Python+OpenCV人臉檢測(cè)原理及示例詳解
- python利用OpenCV2實(shí)現(xiàn)人臉檢測(cè)
- python結(jié)合opencv實(shí)現(xiàn)人臉檢測(cè)與跟蹤
- python中使用OpenCV進(jìn)行人臉檢測(cè)的例子
- 使用 Python 和 OpenCV 實(shí)現(xiàn)攝像頭人臉檢測(cè)并截圖功能
相關(guān)文章
python 動(dòng)態(tài)生成變量名以及動(dòng)態(tài)獲取變量的變量名方法
今天小編就為大家分享一篇python 動(dòng)態(tài)生成變量名以及動(dòng)態(tài)獲取變量的變量名方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-01-01Python實(shí)現(xiàn)將列表拆分為大小為N的塊
這篇文章主要為大家整理了一些常見的Python實(shí)現(xiàn)將列表拆分為大小為N的塊的方法,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,有需要的小伙伴可以了解下2023-09-09Python基礎(chǔ)教程(一)——Windows搭建開發(fā)Python開發(fā)環(huán)境
這篇文章主要介紹了Windows如何搭建開發(fā)Python開發(fā)環(huán)境,幫助大家開始學(xué)習(xí)Python,感興趣的朋友可以了解下2020-07-07python中np.random.permutation函數(shù)實(shí)例詳解
np.random.permutation是numpy中的一個(gè)函數(shù),它可以將一個(gè)數(shù)組中的元素隨機(jī)打亂,返回一個(gè)打亂后的新數(shù)組,下面這篇文章主要給大家介紹了關(guān)于python中np.random.permutation函數(shù)的相關(guān)資料,需要的朋友可以參考下2023-04-04Pytest?fixture及conftest相關(guān)詳解
這篇文章主要介紹了Pytest?fixture及conftest相關(guān)詳解,fixture是在測(cè)試函數(shù)運(yùn)行前后,由pytest執(zhí)行的外殼函數(shù),更多相關(guān)內(nèi)容需要的朋友可以參考一下2022-09-09詳解Django中 render() 函數(shù)的使用方法
這篇文章主要介紹了Django中 render() 函數(shù)的使用方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04python Django框架實(shí)現(xiàn)自定義表單提交
這篇文章主要為大家詳細(xì)介紹了Django框架實(shí)現(xiàn)自定義表單提交,針對(duì)"表單提交"和"Ajax提交"兩種方式來解決CSRF帶來的錯(cuò)誤進(jìn)行講解,感興趣的小伙伴們可以參考一下2016-03-03