在测试色度图像识别的过程中顺便测试的一段使用OpenCV自带特征库对Camera进行人脸识别的Demo,识别率不错。但身份认证的算法一般,这里也就没有提供 pHash 的代码。
import os, glob import sys import cv2 import numpy as np from PIL import Image,ImageDraw,ImageColor import time import pHash #身份匹配 def comp_faces(faceImgs,faceImg, size=(32,32),part_size=(8,8)): min_code = 1000 for key in faceImgs: code = pHash.classify_DCT(faceImgs[key],faceImg, size,part_size) print(key,' : ',code) if code < min_code: min_code = code uname = key if min_code > 20: return "Who am I ?" else: return "I'm " + uname #人脸识别 def detectFaces(image_path, ispath=1): if ispath == 1: img = cv2.imread(image_path) else: img = image_path #face_cascade = cv2.CascadeClassifier("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml") face_cascade = cv2.CascadeClassifier("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml") if img.ndim == 3: gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) else: gray = img #faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(10,10), flags=cv2.CASCADE_SCALE_IMAGE) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5, minSize=(30,30), flags=cv2.CASCADE_SCALE_IMAGE) #detectMultiScale(args) # 2.scaleFactor 每次图像尺寸减小的比例,尺度越大,越容易漏掉检测的对象,但检测速度加快;尺度越小,检测越细致准确 # 3.minNeighbors 表示每一个目标至少要被检测到3次才算是真的目标 # 4.minSize 目标的最小尺寸 # 5.maxSize 目标的最大尺寸 return faces def get_faces(): every_faces = {} for image_file in glob.glob('pic/face/*_face.jpg'): spx = image_file.split('_')[0].split('/') spxLen = len(spx) - 1 every_faces[spx[spxLen]] = Image.open(image_file) return every_faces def get_cam(todo, faceImg='', times=0): if todo == 'cface': every_face1 = get_faces() # 从摄像头中取得视频 cap = cv2.VideoCapture(0) # 获取视频播放界面长宽 #width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH) + 0.5) #height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT) + 0.5) # 定义编码器 创建 VideoWriter 对象 #fourcc = cv2.VideoWriter_fourcc(*'mp4v') # Be sure to use the lower case #out = cv2.VideoWriter('pic/output.mp4', fourcc, 20.0, (width, height)) #头像标注 show_txt = 'Scan...' sec = 0 while(cap.isOpened()): if todo == 'gface': sec = int(time.time()) - times show_txt = 'Scan...' + str(sec) #读取帧摄像头 ret, frame = cap.read() if ret == True: #输出当前帧 #out.write(frame) faces = detectFaces(frame, 0) #获取头像 if todo == 'gface' and os.path.exists(faceImg)!=True: if len(faces) == 1: if sec>=5: todo = '' for (x, y, w, h) in faces: #cropped = frame[y-180:y+h+80, x-50:x+w+50] cropped = frame[y:y+h, x:x+w] cv2.imwrite(faceImg, cropped) #cv2.imshow("ImgShow", cropped) show_txt = 'Scan Success !' else: show_txt = 'Too many people !' for (x, y, w, h) in faces: #识别头像 if todo == 'cface': #OpenCV_data=np.asarray(PIL_data) #cam_face = Image.fromarray(cam_face_x) cropped = frame[y:y+h, x:x+w] frameImg = Image.fromarray(cropped) show_txt = comp_faces(every_face1, frameImg) #标注头像 cv2.rectangle(frame, (x,y),(x+w, y+h), (0, 255, 0), 2) font = cv2.FONT_HERSHEY_COMPLEX cv2.putText(frame,show_txt, (x,y), font, 1, (255,255,255), 2, cv2.LINE_AA) cv2.imshow('Camera Test',frame) #键盘 q 退出 if (cv2.waitKey(1) & 0xFF) == ord('q'): break else: break # 释放资源 #out.release() cap.release() cv2.destroyAllWindows() __all__ = [get_cam] if __name__ == '__main__': times = int(time.time()) #get_cam('cface') #get_cam('gface', 'pic/face/'+sys.argv[2]+'_face.jpg', times) try: todo = sys.argv[1] if todo == 'gface': if len(sys.argv) != 3: raise Exception() get_cam('gface', 'pic/face/'+sys.argv[2]+'_face.jpg', times) if todo == 'cface': get_cam('cface') except Exception as e: print('Usage:') print(' 采集面部身份') print(' - $main.py gface face-username') print(' 面部身份识别') print(' - $main.py cface')