用opencv操作本地摄像机,实现自定义数量照片截取并命名,通过按键方式实现不同角度拍摄,提高训练精度。具体解释都在代码里面,不一一赘述。
# coding=utf8
import cv2
# 收集人脸照片
cap = cv2.VideoCapture(0) # 视频图像化
# 0表示打开笔记本内置摄像头 ==》可以换成视频路径“/目标地址”
num = 1
while cap.isOpened(): # 检测是否在开启状态
tenser, V_show = cap.read()
# cap.read 表示按帧读取视频
# 用两个参数接收返回值 参数一:布尔值 参数二:每一帧图像,三维矩阵
k = cv2.waitKey(1) & 0xFF
# 键盘的十六进制表示 s=0xFF
# cv2.waitKey() 方法本身表示等待键盘输入 参数为1则为延时1ms切换到下一帧图像 参数为0则只显示当前帧图像
cv2.imshow('camera', V_show) # 显示图像
if k == ord('s'): # 按s键保存
# 文件命名
name = 'D:/Python_Work_Space/python_csdn_face/face2/img_face/' + str(num) + '_liuyang' + '.jpg'
cv2.imwrite(name, V_show)
num = num + 1
# time.sleep(0.5)
# cv2.imwrite 保存图像(保存地址,图像(三维矩阵))
print('保存成功' + name)
num += 1
elif k == ord(' '): # 识别空格退出
break
# 释放摄像头
cap.release()
cv2.destroyAllWindows()
# 关闭所有图像窗口
import os
import cv2
from PIL import Image
import numpy as np
def face_train(path):
# 储存人脸数据
facesSamples = []
ids = []
# 储存图片信息
imagePaths = [os.path.join(path, i) for i in os.listdir(path)]
# 加载分类器
face_detector = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
# 遍历列表中的图片
for imagePath in imagePaths:
# 打开图片,PIL有九种不同的模式:1,L,P,RGB,RGBA,CMYK,YCbCr,I,F
PIL_img = Image.open(imagePath).convert('L')
# L表示灰度图像,每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同灰度
# 转化公式 L = R * 299 / 1000 + G * 587 / 1000 + B * 114 / 1000。
# 将图像转化为数组,以黑白深浅 image转array
img_numpy = np.array(PIL_img)
# 获取图片人脸特征
faces = face_detector.detectMultiScale(img_numpy)
# opencv中人脸检测使用的是 detectMultiScale 函数。
# 它可以检测出图片中所有的人脸,并将人脸用vector保存各个人脸的坐标、大小(用矩形表示),
# 拿到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("id",id)
print('面部特征矩阵:', facesSamples)
return facesSamples,ids
if __name__ == '__main__':
# 图片路径
path = 'img_face/'
# 获取图像数组和id标签数组和姓名
faces,ids = face_train(path)
# 加载识别器
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 训练
recognizer.train(faces, np.array(ids))
# 保存文件
recognizer.write('liuyang.yml')
import cv2
# 加载训练数据文件
recogizer = cv2.face.LBPHFaceRecognizer_create()
# 加载数据
recogizer.read("liuyang.yml")
# 名称
names = []
# 报警全局变量
warningtime = 0
# 准备识别的图片
def face_detect_demo(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为灰度
face_detector = cv2.CascadeClassifier('D:/Python_Work_Space/python_csdn_face/face2\haarcascade_frontalface_alt.xml')
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]) # 对测试数据进行分类 返回值和返回结果
if confidence > 80:
global warningtime
warningtime += 1
if warningtime > 100:
warningtime = 0
# 图片 添加的文字 位置 字体 字体大小 字体颜色 字体粗细
cv2.putText(img, 'unkonw', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
else:
cv2.putText(img, "liu", (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
cv2.imshow('result', img)
# 名字标签
def name():
names.append("liu")
# 加载视频
cap = cv2.VideoCapture(0)
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()