总计分为三个步骤
一、捕获人脸照片
二、对捕获的照片进行训练
三、加载训练的数据,识别
使用python3.6.8,opencv,numpy,pil
第一步:通过笔记本前置摄像头捕获脸部图片
将捕获的照片存在picData文件夹中,并格式为user.id.num.jpg。id在识别时和人名数组一一对应。
import numpy as np import cv2 cap = cv2.VideoCapture(0) face_cascade = cv2.CascadeClassifier("data/haarcascade_frontalface_default.xml") sampleNum = 0 Id = input('请输入id:') while True: ret, img = cap.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x, y, w, h) in faces: img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) # 增加例子数 sampleNum = sampleNum + 1 # 把照片保存到数据集文件夹 cv2.imwrite( "picData/user." + str(Id) + "." + str(sampleNum) + ".jpg", gray[y : y + h, x : x + w], ) cv2.imshow("img", img) if cv2.waitKey(1) & 0xFF == ord("q"): break if sampleNum == 3000: break cap.release() cv2.destroyAllWindows()
第二步:训练数据
将训练好的数据存储在data/trainner.yml中
import cv2 import os import numpy as np from PIL import Image recognizer = cv2.face.LBPHFaceRecognizer_create() detector = cv2.CascadeClassifier("data/haarcascade_frontalface_default.xml") def get_images_and_labels(path): image_paths = [os.path.join(path, f) for f in os.listdir(path)] face_samples = [] ids = [] for image_path in image_paths: image = Image.open(image_path).convert("L") image_np = np.array(image, "uint8") if os.path.split(image_path)[-1].split(".")[-1] != "jpg": continue image_id = int(os.path.split(image_path)[-1].split(".")[1]) faces = detector.detectMultiScale(image_np) for (x, y, w, h) in faces: face_samples.append(image_np[y : y + h, x : x + w]) ids.append(image_id) return face_samples, ids faces, Ids = get_images_and_labels("picData") recognizer.train(faces, np.array(Ids)) recognizer.save("data/trainner.yml")
第三步:人脸识别
加载第二步训练的数据,定义需要识别的人名。
import cv2 recognizer = cv2.face.LBPHFaceRecognizer_create() recognizer.read('data/trainner.yml') faceCascade = cv2.CascadeClassifier("data/haarcascade_frontalface_default.xml") font = cv2.FONT_HERSHEY_SIMPLEX idnum = 0 names = ['kAng'] cam = cv2.VideoCapture(0) minW = 0.1*cam.get(3) minH = 0.1*cam.get(4) while True: ret, img = cam.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale( gray, scaleFactor=1.2, minNeighbors=5, minSize=(int(minW), int(minH)) ) for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) idnum, confidence = recognizer.predict(gray[y:y+h, x:x+w]) if confidence >50: idnum = names[idnum] confidence = "{0}%".format(round(confidence)) else: idnum = "unknown" confidence = "{0}%".format(round(confidence)) cv2.putText(img, str(idnum), (x+5, y-5), font, 1, (0, 0, 255), 1) cv2.putText(img, str(confidence), (x+5, y+h-5), font, 1, (255, 255, 0), 1) cv2.imshow('camera', img) k = cv2.waitKey(10) if k == 27: break cam.release() cv2.destroyAllWindows()
效果图: