基于Python+OpenCv的人脸口罩识别系统附模型训练
以下编程在PyCharm平台上进行
面对突如其来的新冠肺炎疫情,疫情防控事关每一个人,检查人员是否佩戴口罩一直是防控的重点,通常情况下,在商场等公共场所有自动测温装置,但是对是否佩戴口罩的检测还是依靠人力来实现,存在疏忽的漏洞,因此开发一款能自动识别人脸口罩佩戴的系统势在必行;
目录
- [一、OpenCV下载安装]
- [二、人脸口罩数据集下载处理]
- [(一)人脸口罩数据集下载]
- [(二)人脸口罩数据集的处理]
- [三、训练人脸口罩数据集模型]
- [四、进行人脸口罩检测]
一、OPENCV下载安装
参考网址:https://blog.csdn.net/cungudafa/article/details/84451066
我们这里直接官网下载(opencv-3.4.16-vc14_vc15):https://opencv.org/releases/
下载好之后直接安装即可(Windows)
二、人脸口罩数据集下载处理
(一)人脸口罩数据集下载
下载人脸口罩数据集的目的是利用OpenCV进行模型训练,这里采用口罩数据集的正负比列为1:3,即500张戴口罩的人脸图片和1500张不戴口罩的人脸图片。
链接:
解压之后,将压缩包中的mask文件自行选择文件夹放置,以便之后的操作。
(二)人脸口罩数据集的处理
1、将数据集重命名为连续序列
因为数据集中的图片序列是不连续的,因此这里需要编程将数据集的正负样本重命名为连续序列,以便像素调整。
重命名正样本序列Python代码:
#对数据集重命名
#coding:utf-8
import os
path = r"C:\Users\14033\Desktop\mask\have_mask" # 人脸口罩数据集正样本的路径
filelist = os.listdir(path)
count = 1000 # 开始文件名1000.jpg
for file in filelist:
Olddir = os.path.join(path, file)
if os.path.isdir(Olddir):
continue
filename = os.path.splitext(file)[0]
filetype = os.path.splitext(file)[1]
Newdir = os.path.join(path, str(count) + filetype)
os.rename(Olddir, Newdir)
count += 1
命名之后,正样本序列如下:
重命名负样本序列Python代码:
#对数据集重命名
#coding:utf-8
import os
path = r"C:\Users\14033\Desktop\mask\no_mask" # 人脸口罩数据集的路径
filelist = os.listdir(path)
count = 10000 # 开始文件名1000.jpg
for file in filelist:
Olddir = os.path.join(path, file)
if os.path.isdir(Olddir):
continue
filename = os.path.splitext(file)[0]
filetype = os.path.splitext(file)[1]
Newdir = os.path.join(path, str(count) + filetype)
os.rename(Olddir, Newdir)
count += 1
重命名之后,负样本序列如下:
2、正负样本数据集像素处理
正样本数据集的像素最佳设为20x20,这样的模型训练精度更高;负样本数据集像素不低于50x50,这样处理可以加快模型训练的速度。
修改正样本数据集像素为20x20Python代码:
# 修改正样本像素
import pandas as pd
import cv2
for n in range(1000, 1606): # 代表正数据集中开始和结束照片的数字
path = 'C:\\Users\\14033\\Desktop\\mask\\have_mask\\' + str(n) + '.jpg'
# 读取图片
img = cv2.imread(path)
img = cv2.resize(img, (20, 20)) # 修改样本像素为20x20
cv2.imwrite('C:\\Users\\14033\\Desktop\\mask\\have_mask20\\' + str(n) + '.jpg', img)
n += 1
修改像素之后,序列如下:
修改负样本数据集像素为80x80Python代码:
#修改负样本像素
import pandas as pd
import cv2
for n in range(10000,11790):#代表负样本数据集中开始和结束照片的数字
path='C:\\Users\\14033\\Desktop\\mask\\no_mask\\'+str(n)+'.jpg'
# 读取图片
img = cv2.imread(path)
img=cv2.resize(img,(80,80)) #修改样本像素为60x60
cv2.imwrite('C:\\Users\\14033\\Desktop\\mask\\no_mask20\\' + str(n) + '.jpg', img)
n += 1
修改像素之后,序列如下:
3、创建正负样本数据集路径的txt文件
(1)创建正样本数据集txt文件
win+R打开窗口输入cmd,进入命令提示符界面,进入have_mask文件夹
输入命令创建路径文件
dir /b/s/p/w *.jpg > have_mask.txt
have_mask.txt文件位置在正样本数据集文件夹中
(2)创建负样本数据集txt文件(方法同正样本数据集一样)
然后将have_mask.txt和no_mask.txt文件放到mask目录下
三、训练人脸口罩数据集模型
1、创建xml文件夹存放训练好的模型
2、将OpenCV安装路径 \opencv\build\x64\vc14\bin下的opencv_createsamples.exe可执行文件和opencv_traincascade.exe可执行文件及另外两个下图文件复制到数据集同级目录,如下所示:
3、对正负样本txt文档进行预处理
正负样本需要生成 .vec格式的文档进行模型训练,因此需要通过对txt文档进行预处理,向have_mask.txt文件中末尾加入 1 0 0 20 20。
正样本处理Python代码:
#正样本文件预处理 没行目录结尾加入 1 0 0 20 20
#coding:utf-8
import os
#Houzui="_Apple"
Houzui=r" 1 0 0 20 20" #后缀
filelist = open('C:\\Users\\14033\\Desktop\\mask\\have_mask.txt','r+',encoding = 'utf-8')
line = filelist.readlines()
for file in line:
file=file.strip('\n')+Houzui+'\n'
print(file)
filelist.write(file)
负样本处理Python代码:
#正样本文件预处理 没行目录结尾加入 1 0 0 80 80
Houzui=r" 1 0 0 80 80" #后缀
filelist = open('C:\\Users\\14033\\Desktop\\mask\\no_mask.txt','r+',encoding = 'utf-8')
line = filelist.readlines()
for file in line:
file=file.strip('\n')+Houzui+'\n'
print(file)
filelist.write(file)
这个处理不会自动覆盖之前的文件内容,所以需要手动将之前的内容剪切出来 ,保存为have_mask1.txt文件,have_mask.txt文件中只保留末尾为1 0 0 20 20的内容,如下:
同理,对no_mask.txt文件执行同样的操作手动将之前的内容剪切出来 ,保存为no_mask1.txt文件,no_mask.txt文件中只保留末尾为1 0 0 80 80的内容,如下:
4、生成正样本havemask.vec文件和nomask.vec文件
这里操作在cmd终端中进行,进入mask文件夹下,输入以下内容:
生成正样本havemask.vec文件:
opencv_createsamples.exe -vec havemask.vec -info have_mask.txt -num 606 -w 20 -h 20
生成负样本nomask.vec文件:
opencv_createsamples.exe -vec nomask.vec -info no_mask.txt -num 1790 -w 80 -h 80
上述命令内容阐述:
- info:样本说明文件
- vec:样本描述文件名和路径
- num:样本个数,这里为606个样本
- w h:样本尺寸,这里为20x20
生成文件如下:
5、训练模型
(1)在mask目录下创建txt文件,写入以下内容:
opencv_traincascade.exe -data xml -vec havemask.vec -bg no_mask.txt -numPos 350 -numNeg 400 -numStages 20 -w 20 -h 20 -mode ALL
pause
(2)将创建的txt文件命名为traincascade.bat
(3)删掉have_mask.txt和no_mask,txt,然后将have_mask1.txt和no_mask1.txt改为have_mask.txt和no_mask.txt
(4)打开traincascade.bat,开始训练人脸口罩数据集模型
在这里训练模型的时间会很长,耐心等待…
训练结束:
四、进行人脸口罩检测
Python代码:
import time
import cv2
import cv2 as cv
n = 0
have_mask = 0
no_mask = 0
# haarcascade_frontalface_alt2.xml 人脸识别文件在opencv库中 pyth37\Lib\site-packages\cv2\data\
# PyCharm 则在对于的虚拟环境中 如虚拟机环境目录\venv\Lib\site-packages\cv2\data\
face_cascade = cv.CascadeClassifier('C:/Users/14033/Desktop/mask/haarcascade/haarcascade_frontalface_alt2.xml')
# 训练出来的口罩识别cascade.xml
mask_detector = cv.CascadeClassifier("C:/Users/14033/Desktop/Face-Mask-Detection/haarcascades/cascade.xml")
cameraCapture = cv2.VideoCapture(0, cv2.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.3, 10) # 1.02
masks = mask_detector.detectMultiScale(gray, 1.2, 5) # 1.01
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 - 10), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
n = 1
have_mask = 1
print("无口罩")
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 - 10), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 1)
n = 1
no_mask = 1
print("有口罩")
c = cv.waitKey(10)
if c == 27:
cameraCapture.release()
break
# 计算帧率
end = time.time() # 结束时间
fps = 1 / (end - start) # 帧率
image = cv.putText(frame, "FPS:{:.1f}".format(fps), (10, 30), cv.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2) # 绘制
cv.imshow('camera', frame)
haarcascade_frontalface_default.xml是Python安装目录下的模型,自带人脸识别模型文件,在此之前需要安装opencv-python库。
运行结果:
评论 (0)