人脸识别登录功能的基本原理是通过对比两张图片的差异度来判断两张图片是
否是同 一人的面部 。 对比图片 差异度 的算法有很多种,本例中使用“颜色直方图”
算法来实现对人脸图像的识别。
下面为比较 imgl 扣g 及 img2.jpg 这两张图片差异度 的程序代码:
import math, operator
from PIL import Image
from functools import reduce
picl = Image.open("F:\\pythonBase\\pythonex\\ch10\\media\\img01.jpg")
pic2 = Image.open("F:\\pythonBase\\pythonex\\ch10\\media\\img01copy1.jpg")
# pic2 = Image.open("F:\\pythonBase\\pythonex\\ch10\\media\\img01.jpg")
hl = picl.histogram()
h2 = pic2.histogram()
diff = math.sqrt(reduce(operator.add,list(map(lambda a ,b: (a-b)**2 ,hl,h2)))/len (hl))
print(diff)
![](https://img2018.cnblogs.com/i-beta/1020928/201912/1020928-20191213050107336-48347673.png)
import math, operator
from PIL import Image
from functools import reduce
picl = Image.open("F:\\pythonBase\\pythonex\\ch10\\media\\img01.jpg")
# pic2 = Image.open("F:\\pythonBase\\pythonex\\ch10\\media\\img01copy1.jpg")
pic2 = Image.open("F:\\pythonBase\\pythonex\\ch10\\media\\img01.jpg")
hl = picl.histogram()
h2 = pic2.histogram()
diff = math.sqrt(reduce(operator.add,list(map(lambda a ,b: (a-b)**2 ,hl,h2)))/len (hl))
print(diff)
![](https://img2018.cnblogs.com/i-beta/1020928/201912/1020928-20191213050203079-317557865.png)
应用程序概述
第一次执行时提示用户 创建用 户面部文件 : 按任意键会打开摄像头,调整摄像
头中的人脸位置与角度,合适后按 Z 键抓取面部区域并保存,分辨率设为 200 × 200 。
![](https://img2018.cnblogs.com/i-beta/1020928/201912/1020928-20191213050536318-959420996.png)
再次执行程序,先提示创建登录用户的面部文件。按任意键会打开摄像头,按
Z 键抓取面部区域井保存。然后与第一次创建的面部文件进行对比,若差异度在 100
内,显示允许登录信息,否则显示面部文件不正确信息。
from PIL import Image
from functools import reduce
import cv2, os, math, operator
casc_path = "E:\\haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(casc_path) #创建识别对象
def makeFace(facename, msg, endstr):
print(msg) #显示提示信息
cv2.namedWindow("frame")
cv2.waitKey(0)
cap = cv2.VideoCapture(0) #打开摄像头
while(cap.isOpened()): #如果摄像头处于打开状态,则...
ret, img = cap.read() #读取图像
if(ret == True): #读取成功
cv2.imshow("frame", img) #显示图像
k = cv2.waitKey(100) #每0.1秒读一次键盘
if((k == ord("z"))or(k == ord("Z"))): #如果输入z
cv2.imwrite(facename,img) #把读取的img保存至facename文件
image = cv2.imread(facename) #读取刚刚保存的facename文件至image变量,作为下面人脸识别函数的参数
faces = faceCascade.detectMultiScale(image, scaleFactor=1.1, minNeighbors=5, minSize=(30,30), flags = cv2.CASCADE_SCALE_IMAGE)
(x, y, w, h) = (faces[0][0], faces[0][1], faces[0][2], faces[0][3]) #取出第一张人脸区域
image1 = Image.open(facename).crop((x, y, x+w, y+h)) #抓取人脸区域的图像并存至image1变量
image1 = image1.resize((200, 200), Image.ANTIALIAS) #把取得的人脸区域的分辨率变为200x200
image1.save(facename) #把经过处理的人脸文件保存至facename文件
break;
cap.release() #关闭摄像头
cv2.destroyAllWindows() #关闭窗口
print(endstr)
return
recogname = "F:\\pythonBase\\pythonex\\ch10\\media\\recogface.jpg" #预存的人脸文件
loginname = "F:\\pythonBase\\pythonex\\ch10\\\\media\\loginface.jpg" #登录者的人脸文件
os.system("cls") #清屏
if(os.path.exists(recogname)): #如果预存的人脸文件已存在
msg = "按任意键创建登录人脸文件。\n摄像头打开后按z键进行拍照对比!"
makeFace(loginname, msg, "") #创建登录者人脸文件
pic1 = Image.open(recogname) #打开预存的人脸文件
pic2 = Image.open(loginname) #打开登录者人脸文件
h1 = pic1.histogram() #取预存片文件的直方图信息
h2 = pic2.histogram() #取登录者图片的直方图信息
diff = math.sqrt(reduce(operator.add, list(map(lambda a,b: (a-b)**2, h1, h2)))/len(h1)) #计算两个图形差异度
if(diff <= 100): #若差度在100内,可通过验证
print("通过验证,欢迎使用本系统! diff=%4.2f" % diff)
else:
print("人脸错误,无法使用本系统! diff=%4.2f" % diff)
else: #如果预存的人脸文件不存在
msg = "按任意键创建预存的人脸文件。\n摄像头打开后按z进行拍照!\n"
endstr = "预存文件建立完成!"
makeFace(recogname, msg, endstr) #建立预存人脸文件
![](https://img2018.cnblogs.com/i-beta/1020928/201912/1020928-20191213052656666-2110676208.png)
经过测试多种图像对比技术,很多时候效果并不理想,本例中采用的频色直 :
方图算法,会受光线强度、背景等因素而影响对比结果。