基于opencv的人脸检测

这里写目录标题

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

一.基本信息

1.导言

输入:图片,视频,可以使用本地,网络,监控摄像头
处理:人脸检测,识别,肢体识别等
输出:
软件:检测到结果通过短信或者其他形式发送
硬件:可以做检测系统

2.应用

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的人脸检测_第1张图片
这里仅仅只是将面部框出来

4.数据录入

cap=cv2.VideoCapture(0)

falg = 1
num = 1

while(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,ids

if __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的人脸检测_第2张图片
这里我是将图片的id改成新闻主持人,每张图片都需要手动去修改,然后合在一起训练,我只训练的这一个数据,因此除了主持人以外的人都是陌生人,比如:
基于opencv的人脸检测_第3张图片

四.总结

总的来说这只是一个调用现成opencv api的系统,繁琐程度远远不如其他训练的系统,因此准确度也就远远达不到其他系统那么高,如果想提高准确度,就得使用yolo技术,安装anaconda,pytroch等等软件以及一些其他库,不然就会出现下面这种情况:
基于opencv的人脸检测_第4张图片
这个图片最左边的人我调了很久,都检测不出来,不知道是接口有局限性还是我调的有问题,不过使用yolo技术就可以检测出来!

你可能感兴趣的:(深度学习,opencv,计算机视觉,python)