波波已经很久没有分享技术类相关内容了。关于人脸识别,波波之前分享了两篇笔记,主要是关于opencv的,但是核心的代码基本上没有分享。
本篇笔记,波波将采用代码注释的方式,帮助新手朋友们更快入门。
一、获取人脸数据:
- import cv2
- cam = cv2.VideoCapture(0) # 启动摄像头
- cam.set(3, 640) # 设置宽
- cam.set(4, 480) # 设置高
- face_detect = cv2.CascadeClassifier(r'C:\Users\20692\Anaconda3\envs\face\Library\etc\haarcascades\haarcascade_frontalcatface.xml') # 选择haar作为分类器
- face_id = input('id here:') # 输入录入的人名(数字)
- count = 1 # 记录拍照数量
- while(count <= 20): # 拍摄二十个样本
- ret, img = cam.read() # 读取摄像头
- cv2.imshow('Look at the camera', img) # 创建实时窗口
- img = cv2.flip(img, 1) # 拍摄
- grayImg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为灰度图像
- faces = face_detect.detectMultiScale(grayImg, 1.2, 5) # 识别灰度图中的人脸
- for (x, y, w, h) in faces: # 获取四角坐标
- cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 0), 2) # 绘制矩形框住人脸
- cv2.imwrite("D:\\faceDetect\\training_data\\" + str(face_id) + '_' + str(count) + '.jpg', grayImg[y:y + h, x:x + w]) # 记录人脸图像
- print('Got:' + str(face_id) + '_' + str(count) + "\n") # 输出进度
- cv2.imshow(str(face_id) + str(count), img) # 展示剪裁结果
- count += 1 # 照片数+1
- k = cv2.waitKey(100) & 0xff # 监测Esc键
- if(k == 27): # 退出循环
- break
- cam.release() # 释放摄像头并删除窗口
- cv2.destroyAllWindows()
二、训练数据模型:
- import numpy as np
- import cv2
- from PIL import Image
- import os
- PATH = "D:\\faceDetect\\training_data\\" # 选择项目路径
- recognize = cv2.face.LBPHFaceRecognizer_create() # 创建面部识别器
- detect = cv2.CascadeClassifier(r"C:\Users\20692\Anaconda3\envs\face\Library\etc\haarcascades\haarcascade_frontalface_default.xml") # 选定haar作为分类器,文件选择正脸
- def getInfo(path): # 获取训练集数据
- imagePath = [os.path.join(path, f) for f in os.listdir(path)] # 路径遍历
- faceSample = [] # 储存训练集人脸坐标集
- labels = [] # 储存图片对应的人名
- for pathFinder in imagePath: # 遍历所有图片
- pil_img = Image.open(pathFinder).convert('L') # 打开图片并用pil转换成黑白
- img_nmp = np.array(pil_img, 'uint8') # 转换为numpy数组
- label = int(os.path.split(pathFinder)[1].split("_")[0]) # 使用split切分路径,获取图片id中的人名
- print('Now reading:' + os.path.split(pathFinder)[1] + '\n') # 输出一下读取的人名
- faces = detect.detectMultiScale(img_nmp) # 检测图片中的人脸
- for (x, y, w, h) in faces: # 获取脸的四角坐标
- faceSample.append(img_nmp[y:y + h, x:x + w]) # 储存坐标
- labels.append(label) # 储存人名
- return faceSample, labels # 返回信息
- faces, labels = getInfo(PATH)
- recognize.train(faces, np.array(labels)) # 训练
- recognize.write('D:\\faceDetect\\trainRes.yml') # 储存模型文件
三、人脸识别:
- import cv2
- recognize = cv2.face.LBPHFaceRecognizer_create() # LBPH面部识别,其实也可以选择fisher之类的
- recognize.read('D:\\faceDetect\\trainRes.yml') # 读取模型
- cascadePath = "C:\\Users\\20692\Anaconda3\\envs\\face\\Library\\etc\\haarcascades\\haarcascade_frontalcatface.xml" # 定义路径
- faceCascade = cv2.CascadeClassifier(cascadePath) # 分类器文件读取
- font = cv2.FONT_ITALIC # 字体Italic
- label = 0
- cam = cv2.VideoCapture(0) # 启动摄像头,设置长宽
- cam.set(3, 640)
- cam.set(4, 480)
- while True:
- ret, img = cam.read() # 读取图像
- img = cv2.flip(img, 1) # 截取图片
- grayImg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 老套路,识别人脸
- faces = faceCascade.detectMultiScale(
- grayImg,
- scaleFactor=1.2,
- minNeighbors=5,
- minSize=(50, 50)
- )
- for(x, y, w, h) in faces: # 还是老套路,画一个矩形框
- cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 0), 2)
- label, confidence = recognize.predict(grayImg[y:y + h, x:x + w]) # 模型预测,返回识别结果和差异度(越小表示越相似)
- if(confidence < 60): # 较为相似的一个阀值
- print(str(label) + ":" + str(confidence)) # 后台输出
- else: # 不确定
- print('Unknown')
- cv2.putText(img, 'You are:' + str(label), (x + 5, y - 5), font, 1,(255, 255, 255), 2) # 打印结果到画面上
- cv2.putText(img, str(int(confidence)) + "%", (x + 5, y - 55), font, 1, (255, 255, 255), 2)
- cv2.imshow('Press ESC to shutdown', img)
- k = cv2.waitKey(10) & 0xff # Esc退出
- if k == 27:
- break
- cam.release()
- cv2.destroyAllWindows()
以上代码是核心中代码片段,希望对新手朋友们有所帮助。