python,opencv-python人脸识别,并且发邮件对镜头前未知人员进行报警

  • 我们在任意一个硬盘的根目录下创建一个Code-project文件夹

  •  在该文件夹下分别创建C-project和Python-project文件夹

  •  在Python-project文件夹下创建face recognition文件夹

  • 用pycharm在该文件夹创建项目

  •  再在该文件夹下创建face_photo文件夹

  •  在根目录下创建main.py,如果已经有了就无需创建

  •  更换国内镜像源

复制链接到仓库URL后点击应用:https://pypi.tuna.tsinghua.edu.cn/simple/
  •  下载所需库

  •  在main中输入代码
# 导入模块
import os
import cv2 as cv
from PIL import Image
import numpy as np
# 发送邮件报警
import smtplib
from email.mime.text import MIMEText

# 判断非英文或拼音退出
def SlowSnail(s):
    up = 0
    low = 0
    for c in s:
        if c.isupper():
            up += 1
        elif c.islower():
            low += 1
    if up + low == len(s):
        return 1
    else:
        return 0


# 保存照片
def savePhoto():
    # 读取摄像头cv.VideoCapture(设备号)
    cap = cv.VideoCapture(0)

    num = 1
    while (cap.isOpened()):  # 检测是否在开启状态
        ret_flag, Vshow = cap.read()  # 得到每帧图像, cap.read(是否有图像True或者false, 图像)
        cv.imshow('Capture_Test', Vshow)
        # 保存图片
        # 按键判断
        k = cv.waitKey(1) & 0xFF
        if k == ord(' '):
            name = input("待识别人员姓名(英文或拼音):")
            # 非英文或拼音退出
            if SlowSnail(name) == 0:
                continue
            cv.imwrite('face_photo/' + str(num) + "." + name + ".jpg", Vshow)
            print('success to save' + str(num) + '.jpg')
            print('-------------------------------')
            num += 1
        elif k == ord('s'):  # 退出
            break
    # 释放内存
    cv.destroyAllWindows()
    # 释放摄像头
    cap.release()


# 数据训练
def getImageAndLabels(path):
    # 储存人脸数据
    facesSamples = []
    # 储存姓名数据
    ids = []
    # 储存图片信息
    imagePaths = [os.path.join(path, f) for f in os.listdir(path)]
    # 加载分类器
    face_detector = cv.CascadeClassifier(
        'venv/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')
    # 遍历列表中的图片
    for imagePath in imagePaths:
        # 打开图片, 灰度化 Pil有九种不同的模式:1(黑白), L(灰度), P, RGB, RGBA, CMYK, YCbCr, I, F
        PIL_img = Image.open(imagePath).convert('L')
        # 将图像转换为数组
        img_numpy = np.array(PIL_img, 'uint8')
        # 获取图片人脸特征 face_detector.detectMultiScale(图像, 缩放倍数, 检测n次人脸才确定, 0, 最小人脸尺寸, 最大人脸尺寸)
        faces = face_detector.detectMultiScale(img_numpy)
        # 获取每张图片的id, 姓名
        id = int(os.path.split(imagePath)[1].split('.')[0])
        # 保存id和面部特征
        for x, y, w, h in faces:
            ids.append(id)
            facesSamples.append(img_numpy[y:y + h, x:x + w])
        # 打印脸部特征, id
        print('id', id)
        print('fs', facesSamples)
        return facesSamples, ids


# 报警模块, 识别非该项目录入人脸, 识别摄像头前不认识的人脸
def warning():
    # 发送邮件
    # 设置服务器所需信息
    # QQ邮箱服务器地址
    mail_host = 'smtp.qq.com'
    # QQ用户名
    mail_user = '2**********5'
    # 密码(部分邮箱为授权码)
    mail_pass = 'i**********f'
    # 邮件发送方邮箱地址
    sender = '2*********@qq.com'
    # 邮件接受方邮箱地址,注意需要[]包裹,这意味着你可以写多个邮件地址群发
    receivers = ['26*********@qq.com']

    # 设置email信息
    # 邮件内容设置
    message = MIMEText('有未知人员在镜头前', 'plain', 'utf-8')
    # 邮件主题
    message['Subject'] = 'warning!!!'
    # 发送方信息
    message['From'] = sender
    # 接受方信息
    message['To'] = receivers[0]

    # 登录并发送邮件
    smtpObj = smtplib.SMTP()
    # 连接到服务器
    smtpObj.connect(mail_host, 25)
    # 登录到服务器
    smtpObj.login(mail_user, mail_pass)
    # 发送
    smtpObj.sendmail(
        sender, receivers, message.as_string())
    # 退出
    smtpObj.quit()
    print('The message was sent successfullyn')


# 准备识别的图片
def face_detect_demo(img):
    # 转换为灰度图片
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    # 加载分类器
    face_detector = cv.CascadeClassifier(
        'venv/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')
    # 获取图片人脸特征 face_detector.detectMultiScale(图像, 缩放倍数, 检测n次人脸才确定, 0, 最小人脸尺寸, 最大人脸尺寸)
    face = face_detector.detectMultiScale(gray, 1.1, 5, cv.CASCADE_SCALE_IMAGE, (50, 50), (300, 300))
    for x, y, w, h in face:
        # 绘制识别框
        cv.rectangle(img, (x, y), (x + w, y + h), color=(0, 0, 255), thickness=2)
        # 人脸识别
        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
            cv.putText(img, 'unkonw', (x + 10, y - 10), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
        else:
            cv.putText(img, str(names[ids - 1]), (x + 10, y - 10), cv.FONT_HERSHEY_SIMPLEX, 0.75, (255, 0, 0), 1)
    # 显示图像
    cv.imshow('result', img)


# 名字标签
def name():
    path = 'face_photo/'
    imagePaths = [os.path.join(path, f) for f in os.listdir(path)]
    for imagePath in imagePaths:
        name1 = str(os.path.split(imagePath)[1].split('.', 2)[1])
        names.append(name1)


# 主进程
# 保存识别图片
savePhoto()

# 数据训练
# 图片路径
path = 'face_photo/'
# 获取图像数组、id标签数组、姓名
face, ids = getImageAndLabels(path)
# 加载识别器
recognizer = cv.face.LBPHFaceRecognizer_create()
# 训练
recognizer.train(face, np.array(ids))
# 保存文件
recognizer.write('trainer.yml')

# 加载训练数据集文件
recogizer = cv.face.LBPHFaceRecognizer_create()
# 加载数据
recogizer.read('trainer.yml')
# 名称
names = []
# 警报全局变量
warningtime = 0

# 读取摄像头cv.VideoCapture(设备号)
# 读取视频:cap = cv.VideoCapture('视频名.后缀')
cap = cv.VideoCapture(0)
name()
# 等待esc退出
while True:
    # cap.read(是否有图像True或者false, 图像)
    flag, frame = cap.read()
    # 没有图像则退出循环, 有图像则调用检测函数
    if not flag:
        break
    face_detect_demo(frame)
    if cv.waitKey(1) == 27:  # 连续读取的时候需要把参数设置为1或更高
        break
# 释放内存
cv.destroyAllWindows()
# 释放摄像头
cap.release()
  • 代码中的报警模块,此处用的是QQ邮箱,需要提前登录球球邮箱网页版点击设置-账户,滑到最下面开启SMTP,并且生成授权码

img

  • 运行无错误后,1、空格拍照,2、输入英文名字或者拼音,3、 循环1和2直到按下s退出,4、按esc退出识别

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇

)">
下一篇>>