深度学习|基于opencv的人脸检测


这里写目录标题

  • 一.基本信息
    • 1.导言
    • 2.应用
    • 3.环境搭建
    • 二.逻辑以及关键代码
    • 1.逻辑分析
    • 关键代码
      • 三.结果分析
    • 四.总结

一.基本信息 1.导言 输入:图片,视频,可以使用本地,网络,监控摄像头
处理:人脸检测,识别,肢体识别等
输出:
软件:检测到结果通过短信或者其他形式发送
硬件:可以做检测系统
2.应用 【深度学习|基于opencv的人脸检测】1.报警系统:当摄像头环境出现一个陌生人时,立即发送信息让用户知晓,达到保护用户的财产的目的。
2.门禁系统:可以用于家庭中,在检测到数据库中的人脸即可直接打开门,如果是陌生人可以发送信息让用户知晓,用户判断是否开门。
3.打卡系统:公司里每个人的出勤情况,在一定的时间段打卡增加打卡次数,达到考勤的效果
3.环境搭建 1.环境配置
python+pycharm+opencv
2.原理
滑动窗口机制,分类器机制等等
二.逻辑以及关键代码 1.逻辑分析 :
1.第三方模块:
Pillow 9.0.0
numpy 1.21.5
opencv-contrib-python 4.5.5.62
opencv-python 4.5.5.62
pip 21.3.1
setuptools 39.1.0
2.首先要识别图片,通过opencv特定的函数将图片的特征以及id拿出来,在加载LBPH识别器将面部身份信息训练整合到一一对应一起写入yml文件里,这样在识别的过程中调用这些文件来辨别是否是熟悉的人。
3.在检测时,先将导入的图片灰度化,在加载分类器进行检测,就是将整张图片的人脸先框起来得到人脸的图片,在进行评分,如果不可靠,就会增加评分,如果评分很大,就说明不可靠,当分数达到一定程度的时候,就会发出警报(警报器借用的短信宝的api,也可以其他的比如邮箱地址的),意思就是陌生人长期在摄像头下徘徊,用户就会受到警报短信。如果这个人评分比较小,即是白名单中的人,就会把名称打在框图上。
4.当摄像头设置在远处时,我们可以借助rtmp协议,我们可以让视频流可以在摄像头和主机电脑之间进行数据传输,目前市面上的摄像头基本都支持这种rtmp协议,API也会在说明书中给出,也可以运用官方的接口进行推流测试,这样就可以远程监控了。
关键代码 1.读取图片关键代码
import cv2 as cv #读取图片 img = cv.imread('1.jpg')#显示图片 cv.imshow('结果',img)

2.绘制矩形关键代码
import cv2 as cv #读取图片 img = cv.imread('1.jpg') #坐标 x,y,w,h= 100,100,100,100 #绘制矩形(在那张图片上画,起始点以及长宽,颜色(蓝,灰,红),宽度) cv.rectangle(img,(x,y,x+h,y+w),color=(0,0,255),thickness=1) #绘制圆形(图像,圆心,半径,颜色,宽度) cv.circle(img,center=(x+w,y+h),radius=100,color=(255,0,0),thickness=3) #显示 cv.imshow('结果',img)

3.人脸检测关键代码
def detectdemo(): gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY) face_detect = cv.CascadeClassifier('D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') #(灰色转换,每次遍历缩放的倍数,检测几次都成功才检测成功,默认0,人脸最小尺寸,人脸最大尺寸) face=detect.detectMultiScale(gray,1.01,50,0,(5,5),(300,300)) for x,y,w,h in face : cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2) cv.imshow('result',img)#读取图片 img = cv.imread('结果.jpg') #建立检测函数 detect_demo()

深度学习|基于opencv的人脸检测
文章图片

这里仅仅只是将面部框出来
4.数据录入
cap=cv2.VideoCapture(0)falg = 1 num = 1while(cap.isOpened()):#检测是否在开启状态 ret_flag,Vshow = cap.read()#得到每帧图像 cv2.imshow("Capture_Test",Vshow)#显示图像 k = cv2.waitKey(1) & 0xFF#按键判断 if k == ord('2'):#保存 cv2.imwrite("D:\pythonprojectall\detect\photo\data"+str(num)+".123"+".jpg",Vshow) print("save"+str(num)+".jpg") print("-------------------") num += 1 elif k == ord(' '):#退出 break #释放摄像头 cap.release() #释放内存 cv2.destroyAllWindows()

如果这里不想通过摄像头录入信息也可以通过图片或者视频录入,一张图对应一个id,将得到的图片一一取好id
5.训练数据
def getImageAndLabels(path): #储存人脸数据 facesSamples=[] #储存ID ids=[] #储存图片信息 imagePaths=[os.path.join(path,f) for f in os.listdir(path)] #检测人脸 face_detector = cv2.CascadeClassifier('D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') #打印数组imagePaths #print('数据排列:',imagePaths) #遍历列表中的图片 for imagePath in imagePaths: #打开图片,黑白化 PIL_img=Image.open(imagePath).convert('L') #将图像转换为数组,以黑白深浅 # PIL_img = cv2.resize(PIL_img, dsize=(400, 400)) img_numpy=np.array(PIL_img,'uint8') #获取图片人脸特征 faces = face_detector.detectMultiScale(img_numpy) #获取每张图片的id和姓名 id = int(os.path.split(imagePath)[1].split('.')[0]) #预防无面容照片 for x,y,w,h in faces: ids.append(id) facesSamples.append(img_numpy[y:y+h,x:x+w]) #打印脸部特征和id #print('fs:', facesSamples) print('id:', id) #print('fs:', facesSamples[id]) print('fs:', facesSamples) #print('脸部例子:',facesSamples[0]) #print('身份信息:',ids[0]) return facesSamples,idsif __name__ == '__main__': #图片路径 path='./photo/' #获取图像数组和id标签数组和姓名 faces,ids=getImageAndLabels(path) #获取训练对象 recognizer=cv2.face.LBPHFaceRecognizer_create() #recognizer.train(faces,names)#np.array(ids) recognizer.train(faces,np.array(ids)) #保存文件 recognizer.write('trainer/trainer.yml') #save_to_file('names.txt',names)

6.人脸识别
```c def face_detect_demo(img): gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换为灰度 face_detector=cv2.CascadeClassifier('D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') face=face_detector.detectMultiScale(gray,1.1,5,cv2.CASCADE_SCALE_IMAGE,(100,100),(300,300)) #face=face_detector.detectMultiScale(gray) for x,y,w,h in face: cv2.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2) cv2.circle(img,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=1) # 人脸识别 ids, confidence = recogizer.predict(gray[y:y + h, x:x + w]) #print('标签id:',ids,'置信评分:', confidence) if confidence > 80: global warningtime warningtime += 1 if warningtime > 100: warning() warningtime = 0 cv2.putText(img, 'unkonw', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1) else: cv2.putText(img,str(names[ids-1]), (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1) cv2.imshow('result',img) #print('bug:',ids)def name(): path = './photo/' #names = [] imagePaths=[os.path.join(path,f) for f in os.listdir(path)] for imagePath in imagePaths: name = str(os.path.split(imagePath)[1].split('.',2)[1]) names.append(name)#cap = cv.VideoCapture(0)#打开摄像头识别 cap=cv2.VideoCapture('1.mp4')#使用视频识别 name() while True: flag,frame=cap.read() if not flag: break face_detect_demo(frame) if ord(' ') == cv2.waitKey(10): break cv2.destroyAllWindows() cap.release()

三.结果分析
最终结果:
深度学习|基于opencv的人脸检测
文章图片

这里我是将图片的id改成新闻主持人,每张图片都需要手动去修改,然后合在一起训练,我只训练的这一个数据,因此除了主持人以外的人都是陌生人,比如:
深度学习|基于opencv的人脸检测
文章图片

四.总结 总的来说这只是一个调用现成opencv api的系统,繁琐程度远远不如其他训练的系统,因此准确度也就远远达不到其他系统那么高,如果想提高准确度,就得使用yolo技术,安装anaconda,pytroch等等软件以及一些其他库,不然就会出现下面这种情况:
深度学习|基于opencv的人脸检测
文章图片

这个图片最左边的人我调了很久,都检测不出来,不知道是接口有局限性还是我调的有问题,不过使用yolo技术就可以检测出来!

    推荐阅读