如果dilb和face_recognition第三方包安装失败,请移步到Python 解决dilb和face_recognition第三方包安装失败_水w的博客-CSDN博客
上篇请移步到Python+dilb 简单实现人脸检测(附代码)_水w的博客-CSDN博客
本篇是在上篇的工作基础上进行的。
目录
6 人脸检测多个
7 视频检测
8 拍照保存
9 训练数据
解决报错AttributeError: module 'cv2' has no attribute 'face'
10 人脸识别
6 人脸检测多个
整个代码如下:
# 导入cv模块
import cv2 as cv# 检测函数
def face_detect_demo():gary = cv.cvtColor(img, cv.COLOR_BGR2GRAY)face_detect = cv.CascadeClassifier('D:/my/python-pycharm/python-envs/venv-deep/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml')face = face_detect.detectMultiScale(gary)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('face2.jpg')
# 检测函数
face_detect_demo()
# 等待
while True:if ord('q') == cv.waitKey(0):break
# 释放内存
cv.destroyAllWindows()
效果如下:
可以看到,大部分的人脸都被检测出来了。在人数很多的情况下,有一个没有被检测到,但在简单的场景下还是能基本完成要求的。
当然,我们也可以改变调用的这个haarcascade_frontalface_alt2.xml文件,换成该路径下的其他的,比如haarcascade_frontalface_default.xml,效果会稍有不同。
7 视频检测
整个代码如下:
# 导入cv模块
import cv2 as cv# 检测函数
def face_detect_demo(img):gary = cv.cvtColor(img, cv.COLOR_BGR2GRAY)face_detect = cv.CascadeClassifier('D:/my/python-pycharm/python-envs/venv-deep/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')face = face_detect.detectMultiScale(gary)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)# 读取摄像头
cap = cv.VideoCapture(0)
# 循环
while True:flag, frame = cap.read()if not flag:breakface_detect_demo(frame)if ord('q') == cv.waitKey(1):break
# 释放内存
cv.destroyAllWindows()
# 释放摄像头
cap.release()
此处就不展示效果了。
8 拍照保存
整个代码如下:
# 导入模块
import cv2# 摄像头
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('s'): # 保存cv2.imwrite("D:/mycodetest/opencv/data/jm/" + str(num) + ".123" + ".jpg", Vshow)print("success to save" + str(num) + ".jpg")print("-------------------")num += 1elif k == ord(' '): # 退出break
# 释放摄像头
cap.release()
# 释放内存
cv2.destroyAllWindows()
此处就不展示效果了。
9 训练数据
整个代码如下:
import os
import cv2
import sys
from PIL import Image
import numpy as npdef getImageAndLabels(path):facesSamples = []ids = []imagePaths = [os.path.join(path, f) for f in os.listdir(path)]# 检测人脸face_detector = cv2.CascadeClassifier('D:/my/python-pycharm/python-envs/venv-deep/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml')# 打印数组imagePathsprint('数据排列:', 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 = './data/jm/'# 获取图像数组和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)
效果如下: 会生成一个文件,文件的路径为trainer/trainer.yml。
解决报错AttributeError: module 'cv2' has no attribute 'face'
场景:在使用cv2.face.LBPHFaceRecognizer_create()进行人脸识别的操作时,会出现这样的提示。
recognizer = cv2.face.LBPHFaceRecognizer_create()
解决方法:之所以出现这种情况,是因为缺少了相关的包。
从官网上我们看到,face模块实际上并不是opencv图书馆的一部分。更确切地说,face是部分的的opencv-contrib库。从自述文件:此存储库[ opencv-contrib]用于开发所谓的“额外”模块,提供功能。新模块通常没有稳定的API,并且它们没有经过良好测试。因此,它们不应作为官方OpenCV发行版的一部分发布,因为该库保持二进制兼容性,并试图提供良好的性能和稳定性。
(1)首先切换到你所在的环境(不建议在base环境中直接下载),接着就是下载我们需要的相关的包,用清华源下载快。
在pycharm的终端中,执行下条命令,
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-contrib-python
安装成功,看到successfully之后就可以重新运行代码了。
ok,问题解决。
10 人脸识别
整个代码如下:
import cv2, os
import numpy as np
# coding=utf-8
import urllib
import urllib.request
import hashlib# 加载训练数据集文件
recogizer = cv2.face.LBPHFaceRecognizer_create()
recogizer.read('trainer/trainer.yml')
names = []
warningtime = 0def md5(str):import hashlibm = hashlib.md5()m.update(str.encode("utf8"))return m.hexdigest()statusStr = {'0': '短信发送成功','-1': '参数不全','-2': '服务器空间不支持,请确认支持curl或者fsocket,联系您的空间商解决或者更换空间','30': '密码错误','40': '账号不存在','41': '余额不足','42': '账户已过期','43': 'IP地址限制','50': '内容含有敏感词'
}def warning():smsapi = "http://api.smsbao.com/"# 短信平台账号user = '13******10'# 短信平台密码password = md5('*******')# 要发送的短信内容content = '【报警】\n原因:检测到未知人员\n地点:xxx'# 要发送短信的手机号码phone = '*******'data = urllib.parse.urlencode({'u': user, 'p': password, 'm': phone, 'c': content})send_url = smsapi + 'sms?' + dataresponse = urllib.request.urlopen(send_url)the_page = response.read().decode('utf-8')print(statusStr[the_page])# 准备识别的图片
def face_detect_demo(img):gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为灰度face_detector = cv2.CascadeClassifier('D:/my/python-pycharm/python-envs/venv-deep/Lib/site-packages/cv2/data/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 warningtimewarningtime += 1if warningtime > 100:warning()warningtime = 0cv2.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 = './data/jm/'# 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 = cv2.VideoCapture('1.mp4')
name()
while True:flag, frame = cap.read()if not flag:breakface_detect_demo(frame)if ord(' ') == cv2.waitKey(10):break
cv2.destroyAllWindows()
cap.release()
# print(names)
如果大家想要使用代码中提到的报警功能,首先需要先去马上使用更好的短信服务-短信宝官网这个网站去注册登录,才有账号。
此处由于我代码里写的账号信息不对,因此pycharm终端输出的是“密码错误”,正常情况下会显示发生短信成功。
效果如下:
由于我们数据训练只加入了路径为./data/jm/1.lena.jpg一张图片,因此当执行代码建人脸识别时,它只能识别出这个叫lena的女孩,其他人脸识别出来都是会标注为“unknow”。