Notes
  1. 步骤:
    样本收集 —-> 训练 —-> 摄像头预测检验
  2. 准备模块:OpenCV , Numpy

1. 准备环境

将 Pycharm 接上 Anaconda 环境的解释器
( 我这里是使用了 Anaconda 环境下 自建的 tensorflow 虚拟环境 )
如图所示

注:记得在 Anaconda Prompt (Anaconda3) 里 提前安装好 opencv 和 opencv-contrib 模块





2.样本收集

使用电脑摄像头进行样本采集
我这里分别采集2个人的样本 (各1000张)

注:

  1. 我这里是将样本数据采集到 “. ./03_DataSet/01_Grocery” 目录下,你可以根据需要自行更改路径
  2. 样本名称我这里统一使用了 image + 序号 .jpg 进行命名,方便后续训练时候进行遍历操作

第一个人:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import cv2

cap = cv2.VideoCapture(0) # 打开摄像头0 / 若为“xxxx.mp4”则为视频文件
isOpened = cap.isOpened() # 判断是否打开/ 为后续提供条件语句
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(fps, width, height)

i = 0
while isOpened:
if i == 1000:
break
else:
i += 1
(flag, frame) = cap.read() # flag是否读取成功, frame为图片内容
fileName = "image" + str(i) + ".jpg"
if flag:
cv2.imwrite(f"../03_DataSet/01_Grocery/{fileName}", frame, [cv2.IMWRITE_JPEG_QUALITY, 100])

cv2.imshow("Hello!", frame)
if cv2.waitKey(1) == ord("q"):
break

print("END")

第二个人:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import cv2

cap = cv2.VideoCapture(0) # 打开摄像头0 / 若为“xxxx.mp4”则为视频文件
isOpened = cap.isOpened() # 判断是否打开/ 为后续提供条件语句
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(fps, width, height)

i = 1000
while isOpened:
if i == 2000:
break
else:
i += 1
(flag, frame) = cap.read() # flag是否读取成功, frame为图片内容
fileName = "image" + str(i) + ".jpg"
if flag:
cv2.imwrite(f"../03_DataSet/01_Grocery/{fileName}", frame, [cv2.IMWRITE_JPEG_QUALITY, 100])

cv2.imshow("Hello!", frame)
if cv2.waitKey(1) == ord("q"):
break

print("END")





3.训练

简述步骤:

  1. 载入OpenCV自带的 haarcascade_frontalface_default.xml 分类器方便检测出 人脸区域
  2. samples_and_labels()函数:用于获取图像的像素数据 以及 给他们分别附上标签 方便后续进行监督学习(这里说明一下:1.path是根据上述的样本所在路径设立的,如果样本在别处,请在这里修改成你自己的路径;)
  3. 使用opencv相关库中的 face模块的 LBPH算法进行训练

Notes:

  1. samples_and_labels()函数实现包含了:读取图片 —> 灰度转换 —> 用face_xml分类器框出人脸区域 —> 在之中收集 图片像素数据 并分别附上 人名标签(1是一个人的图片数据,2是另一个人的图片数据。。。如此类推)—> 返回人脸数据
  2. 我在11000 附上了 标签1 10012000 附上标签2 ( 2个人 )
  3. train函数: 参数1 为人脸像素数据 参数2 为对应人脸标签
  4. 将数据保存到本目录下的 jackData_trainner.yml 文件内
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    import cv2
    import numpy as np

    face_xml = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')


    def samples_and_labels():
    faceData = []
    ids = []
    for i in range(1, 2000):
    path = "../03_DataSet/01_Grocery/image" + str(i) + ".jpg"
    img = cv2.imread(path)
    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_xml.detectMultiScale(imgGray)

    for (x, y, w, h) in faces:
    if i <= 1000:
    ids.append(1)
    else:
    ids.append(2)
    faceData.append(imgGray[y:y+h, x:x+w])

    return faceData, ids


    (faces, ids) = samples_and_labels()
    print(faces, ids)
    print("Training...")
    jackData = cv2.face.LBPHFaceRecognizer_create() # 创建LBPH

    jackData.train(faces, np.array(ids)) # 参数1 为人脸像素数据 参数2 为对应人脸标签
    jackData.save("jackData_trainner.yml")
    print("Finish")





4.摄像头人脸检测

说明一下:

  1. names收集的人名 对应着 训练模型中 ids-1
  2. confidence变量的 数值越大 则置信度越低(就是越不像)
  3. if ord(“q”) == cv2.waitKey(1):
     break 
    
    这个代码 功能为 按下q 键 退出摄像头检测
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import cv2
import numpy as np

recog = cv2.face.LBPHFaceRecognizer_create()
recog.read("jackData_trainner.yml")
face_xml = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

names = ["name1", "name2"]


cap = cv2.VideoCapture(0)
isOpened = cap.isOpened()

while(isOpened):
(flag, frame) = cap.read()
frameGray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
face = face_xml.detectMultiScale(frameGray, 1.4, 3)

for(x, y, w, h) in face:
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 255, 1), 2, cv2.LINE_AA)
ids, confidence = recog.predict(frameGray[y:y+h, x:x+w])
print(confidence)
if confidence > 70:
cv2.putText(frame, "Who are you?", (x, y-8), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2)
else:
cv2.putText(frame, names[ids-1], (x, y-8), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2)

cv2.imshow("test", frame)
if ord("q") == cv2.waitKey(1):
break





最后附上效果图片:

在这里插入图片描述

附:完整Python代码下载 https://download.csdn.net/download/Panzer_Jack/85609567