如果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:
break
face_detect_demo(frame)
if ord('q') == cv.waitKey(1):
break
# 释放内存
cv.destroyAllWindows()
# 释放摄像头
cap.release()
此处就不展示效果了。
8 拍照保存
整个代码如下:
# 导入模块
import cv2
# 摄像头
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('s'): # 保存
cv2.imwrite("D:/mycodetest/opencv/data/jm/" + str(num) + ".123" + ".jpg", Vshow)
print("success to save" + str(num) + ".jpg")
print("-------------------")
num += 1
elif k == ord(' '): # 退出
break
# 释放摄像头
cap.release()
# 释放内存
cv2.destroyAllWindows()
此处就不展示效果了。
9 训练数据
整个代码如下:
import os
import cv2
import sys
from PIL import Image
import numpy as np
def 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')
# 打印数组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 = './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 = 0
def md5(str):
import hashlib
m = 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?' + data
response = 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 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 = './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:
break
face_detect_demo(frame)
if ord(' ') == cv2.waitKey(10):
break
cv2.destroyAllWindows()
cap.release()
# print(names)
如果大家想要使用代码中提到的报警功能,首先需要先去马上使用更好的短信服务-短信宝官网这个网站去注册登录,才有账号。
此处由于我代码里写的账号信息不对,因此pycharm终端输出的是“密码错误”,正常情况下会显示发生短信成功。
效果如下:
由于我们数据训练只加入了路径为./data/jm/1.lena.jpg一张图片,因此当执行代码建人脸识别时,它只能识别出这个叫lena的女孩,其他人脸识别出来都是会标注为“unknow”。