4 训练数据
4.1 准备
准备工作
- 下载训练数据 ‘orl_faces’
- def前面该装的都装好。
- project<new<directory<data<jm
- project<new<directory<trainer
4.2 训练过程
import os
import cv2 as cv
import numpy as np
import sys
from PIL import Image
def getImageAndLabels(path):
# 建立数组,然后往里面填数据
facesSamples = []
ids = []
# os.listdir(path)获取文件,遍历名称
imagePaths = [os.path.join(path, f) for f in os.listdir(path)]
print(imagePaths)
face_detector = cv.CascadeClassifier(
'D:/LenovoQMDownload/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
# 遍历列表中的图片
for imagePath in imagePaths:
# 打开图片,调用open,返回PIL_img
PIL_img = Image.open(imagePath).convert('L')
# 将图片转换成数组
img_numpy = np.array(PIL_img, 'uint8')
faces = face_detector.detectMultiScale(img_numpy)
# 获取每张图片的id,切分图像的'路径'和'名称+后缀'
print(os.path.split(imagePath))
id = int(os.path.split(imagePath)[1].split('.')[0])
for x, y, w, h in faces:
# 提取人脸,进行切片img_numpy[y:y+h, x:x+w],然后放到facesSamples中
facesSamples.append(img_numpy[y:y+h, x:x+w])
ids.append(id)
return facesSamples, ids
if __name__ == '__main__':
# 获取图片路径
path ='./data/jm/'
# 获取图像数组和id标签数组
faces, ids = getImageAndLabels(path)
# 获取循环对象
recognizer = cv.face.LBPHFaceRecognizer_create()
# 将ids列表转换成数组
recognizer.train(faces, np.array(ids))
# 保存文件
recognizer.write('trainer/trainer.yml')
结果
['./data/jm/1.pgm', './data/jm/10.pgm', './data/jm/11.pgm', './data/jm/12.pgm', './data/jm/13.pgm', './data/jm/14.pgm', './data/jm/15.pgm', './data/jm/2.pgm', './data/jm/3.pgm', './data/jm/4.pgm', './data/jm/5.pgm', './data/jm/6.pgm', './data/jm/7.pgm', './data/jm/8.pgm', './data/jm/9.pgm']
('./data/jm', '1.pgm')
('./data/jm', '10.pgm')
('./data/jm', '11.pgm')
('./data/jm', '12.pgm')
('./data/jm', '13.pgm')
('./data/jm', '14.pgm')
('./data/jm', '15.pgm')
('./data/jm', '2.pgm')
('./data/jm', '3.pgm')
('./data/jm', '4.pgm')
('./data/jm', '5.pgm')
('./data/jm', '6.pgm')
('./data/jm', '7.pgm')
('./data/jm', '8.pgm')
('./data/jm', '9.pgm')
4.2.1 训练过程问题
列表输出顺序错乱
报错:module ‘cv2.face’ has no attribute 'LBPHFaceReconizer_creat
是的,没错,单词 ‘Reconizer’ 写错了!
报错:module ‘cv2.cv2’ has no attribute ‘face’
解决:
安装他俩解决
opencv-python
opencv-contrib-python
4.3 问题解决方案
4.3.1 列表排序函数
result = ["1.pgm", "11.pgm", "2.pgm" , "10.pgm"]
def return_sort_list(result):
new_result = [int(value.split(".")[0]) for value in result]
new_result.sort()
my_result = [str(num) + ".pgm" for num in new_result]
return my_result
new_list = return_sort_list(result)
print(new_list)
['1.pgm', '2.pgm', '10.pgm', '11.pgm']
4.3.1 sort拆分排序
-
把列表中的每一个文件名的数字获取,放到一个列表里面
-
对数字列表进行排序
-
给数字列表的中每一个数字加上.png
result = ["1.pgm", "11.pgm", "2.pgm" , "10.pgm"]
new_result = [int(value.split(".")[0]) for value in result]
new_result.sort()
print(new_result)
my_result = [str(num) + ".pgm" for num in new_result]
print(my_result)
[1, 2, 10, 11]
['1.pgm', '2.pgm', '10.pgm', '11.pgm']
4.3.1 文件名获取过程
import os
imagePath = "/a/imgs/1.png"
# 获取路径中的文件名
file_name = os.path.basename(imagePath)
print(file_name)
# 分别获取整个文件的文件名和后缀
name, end_str = os.path.splitext(file_name)
print(name, end_str)
num = int(name)
print(num, type(num))
1.png
1 .png
1 <class 'int'>
num = int(os.path.splitext(os.path.basename(imagePath))[0])
print(num)