本文主要介绍Python对人脸识别的实现。首先抓取多张图片,从中获取特征数据集和平均特征值,然后写入csv文件——计算特征数据集的欧氏距离进行比较。我们来看看具体的实现过程。
使用的库:dlib Opencv python版本:3.8编译环境:Jupyter Notebook (Anaconda3)
0.Dlib人脸特征检测原理
提取特征点:首先抓取几张图片,从中获取特征数据集和平均特征值,然后写入csv文件——计算特征数据集的欧氏距离进行比较:首先使用Opencv库对相机中的人脸进行分帧,然后将相机中拍摄的特征值与数据集中每个人的特征值进行比较,选择最接近的值(最小的欧氏距离),标记为欧氏距离最小的数据集的名称。
一、构建人脸特征数据集
安装Dlib来构建您自己的数据集
抓取人脸图片:
抓取视频流中的人脸特征,总共保存为256*256的图片文件。这是我们建立数据集训练人脸识别的第一步。
不一定要256*256。可以根据自己的需要调整大小。图片越大,训练结果越准确,但也会影响模型的训练时间。
其中:
光线:曝光和暗图需要手动去除——请使用同一台设备采集数据,但不同设备的摄像头采集的数据不一样——这里可以从视频流中截图,也可以自己准备20张左右的人脸图片。
代码:
导入cv2
导入dlib
导入操作系统
导入系统
随机导入
#存储位置
output _ dir=' d:/no1 workspace/jupyternebook/facetrainset/numname ' #在此填写编号的名称。
尺寸=256 #图像边长
如果不是os.path.exists(输出目录):
os.makedirs(输出目录)
#更改图片的亮度和对比度
定义重新照明(img,light=1,bias=0):
w=img.shape[1]
h=img.shape[0]
#image=[]
对于范围(0,w)内的I:
对于范围(0,h)中的j:
对于范围(3)中的c:
tmp=int(img[j,I,c]*轻偏置)
如果tmp 255:
tmp=255
elif tmp 0:
tmp=0
img[j,I,c]=tmp
返回img
#使用dlib自带的frontal _ face _ detector作为我们的特征提取器。
detector=dlib . get _ frontier _ face _ detector()
#打开相机参数是输入流,可以是相机或视频文件。
相机=cv2。视频捕获(0)
#相机=cv2。video capture(' C:/Users/CUNGU/Videos/Captures/Wang . MP4 ')
指数=1
虽然正确:
If (index=20):#存储15个面部特征图像
打印(“正在处理的图片% s“%索引”)
#从相机中读取照片
success,img=camera.read()
#转换为灰度图片
gray_img=cv2.cvtColor(img,cv2。COLOR_BGR2GRAY)
#使用检测器进行面部检测
dets=检测器(gray_img,1)
对于枚举中的I,d(dets):
x1=d.top() if d.top() 0 else 0
y1=d . bottom()if d . bottom()0 else 0
x2=d.left() if d.left() 0 else 0
y2=d.right() if d.right() 0 else 0
face=img[x1:y1,x2:y2]
#调节画面的对比度和亮度。对比度和亮度值是随机数,可以增加样本的多样性。
face=relight(face,random.uniform(0.5,1.5),random.randint(-50,50))
face=cv2.resize(face,(size,size))
cv2.imshow('image ',face)
cv2 . im write(output _ dir '/' str(index)'。jpg ',脸)
指数=1
key=cv2.waitKey(30)0xff
如果key==27:
破裂
否则:
打印('完成!')
#释放相机释放相机
camera.release()
#删除已建立的窗口删除所有的窗口
cv2.destroyAllWindows()
破裂
运行效果:
分析每张人脸的特征值并存入csv文件:
根据捕获的图片和人脸识别模型-20训练得到的68个特征数据集和1个平均特征值存储在csv文件中。
不需要访问每个图片的68个特征数据集。它们只是中间量,计算平均值后可以丢弃。这里输出只是为了方便学习。
代码:
# 从人脸图像文件中提取人脸特征存入战斗支援车
#从图像中提取特征并保存到features _ all.csv中
# return _ 128d _功能()获取某张图像的128D特征
#计算平均值()计算128D特征均值
从cv2导入cv2作为cv2
导入操作系统
导入dlib
从撇除导入超正析象管
导入战斗支援车
将numpy作为铭牌导入
# 要读取人脸图像文件的路径
path _ images _ from _ camera=' D:/no1 workspace/JupyterNotebook/Facetrainset/'
# Dlib正向人脸检测器
检测器=dlib。get _ frontier _ face _ detector()
# Dlib人脸预测器
预测值=dlib。shape _ predictor(' D:/no1 workspace/JupyterNotebook/model/shape _ predictor _ 68 _ face _ landmarks。dat’)
# Dlib人脸识别模型
#人脸识别模型,该对象将人脸映射到128D向量中
face _ rec=dlib。face _ recognition _ model _ v1(' D:/no1 workspace/JupyterNotebook/model/dlib _ face _ recognition _ resnet _ model _ v1。dat’)
# 返回单张图像的128D特征
def return _ 128d _ features(path _ img):
img_rd=io.imread(path_img)
img_gray=cv2.cvtColor(img_rd,cv2 .COLOR_BGR2RGB)
faces=detector(img_gray,1)
打印(' %-40s %-20s' %('检测到人脸的图像/检测到人脸的图像:",path_img)," \n ")
# 因为有可能截下来的人脸再去检测,检测不出来人脸了
# 所以要确保是检测到人脸的人脸图像拿去算特征
如果len(脸)!=0:
形状=预测值(img_gray,faces[0])
face _ descriptor=face _ rec。compute _ face _ descriptor(图像灰度,形状)
否则:
face_descriptor=0
打印("没有脸")
返回面部描述符
# 将文件夹中照片特征提取出来,写入战斗支援车
def return _ features _ mean _ personX(path _ faces _ personX):
features_list_personX=[]
photos _ list=OS。列表目录(路径_面孔_人员)
如果照片_列表:
对于范围内的我(len(photos _ list)):
打开(' D:/no1 workspace/JupyterNotebook/feature/features gaio ' str(I)' .csv ',' w ',newline=' ')作为CSV文件:
writer=csv.writer(csvfile)
# 调用return _ 128d _功能()得到128d特征
打印(' %-40s %-20s' %('正在读的人脸图像/image to read:',path _ faces _ personX '/' photos _ list[I]))
features _ 128d=return _ 128d _ features(path _ faces _ personX '/' photos _ list[I])
打印(功能_128d)
writer.writerow(features_128d)
# 遇到没有检测出人脸的图片跳过
如果功能_128d==0:
i=1
否则:
功能_列表_人员x。追加(features _ 128d)
否则:
打印('文件夹内图像文件为空/警告:在path_faces_personX '/'中没有图像,' \n ')
# 计算128D特征的均值
# N x 128D - 1 x 128D
if features_list_personX:
features _ mean _ personX=NP。array(features _ list _ personX).平均值(轴=0)
否则:
features_mean_personX='0 '
返回特征_平均值_人员x
# 读取某人所有的人脸图像的数据
人=OS。listdir(路径_图像_来自_照相机)
people.sort()
用打开(' D:/no1 workspace/JupyterNotebook/feature/features _ all。csv ',' w ',newline=' ')作为战斗支援车文件:
writer=csv.writer(csvfile)
对于《人物》中的人物:
打印(' ##### '人员' ##### ')
#获取脸/人x的均值/平均特征,这将是一个长度为128D的列表
features _ mean _ personX=return _ features _ mean _ personX(path _ images _ from _ camera person)
作家。writerow(features _ mean _ personX)
打印('特征均值/功能的平均值:',list(features_mean_personX))
打印(' \n ')
打印('所有录入人脸数据存入/保存注册到:D的所有人脸特征:/我的工作区/JupyterNotebook/People/feature/features _ all 2。CSV’)
如果要输出每一张图片的特征数据集,这里要用到计算机编程语言的文件批量生成。
代码运行效果:
二、识别人脸并匹配数据集
1. 原理
通过计算特征数据集的欧氏距离作对比来识别人脸,取欧氏距离最小的数据集进行匹配。
欧氏距离也称欧几里得距离或欧几里得度量,是一个通常采用的距离定义,它是在m维空间中两个点之间的真实距离。在二维和三维空间中的欧氏距离的就是两点之间的距离。使用这个距离,欧氏空间成为度量空间。相关联的范数称为欧几里得范数。较早的文献称之为毕达哥拉斯度量。
二维空间公式:
2. 视频流实时识别人脸数据
代码:
# 摄像头实时人脸识别
导入操作系统
导入dlib #人脸处理的库Dlib
导入csv #存入表格
导入时间
导入系统
将numpy作为np #导入数据处理的库numpy
从cv2导入cv2作为cv2 #图像处理的库OpenCv
将熊猫作为pd #导入数据处理的库熊猫
# 人脸识别模型,提取128D的特征矢量
#人脸识别模型,该对象将人脸映射到128D向量中
#参考本教程:http://dlib。net/python/index。html # dlib。人脸识别模型v1
facerec=dlib。face _ recognition _ model _ v1(' D:/no1 workspace/JupyterNotebook/model/dlib _ face _ recognition _ resnet _ model _ v1。dat’)
# 计算两个128D向量间的欧式距离
#计算两个128D特征之间的e距离
def return _ euclidean _ distance(feature _ 1,feature_2):
特征_1=np.array(特征_1)
特征_2=np.array(特征_2)
dist=NP。sqrt(NP。sum(NP。正方形(特征1-特征2)))
返回区
# 处理存放所有人脸特征的战斗支援车
path _ features _ known _ CSV=' D:/no1 workspace/JupyterNotebook/feature/features _ all。CSV '
CSV _ rd=PD。read _ CSV(路径_特征_已知_ CSV,头=无)
# 用来存放所有录入人脸特征的数组
#在数据库中保存人脸特征的数组
features_known_arr=[]
# 读取已知人脸数据
#打印已知面孔
对于范围内的我(CSV _ rd。形状[0]):
features_someone_arr=[]
对于范围内的j(0,len(csv_rd.loc[i,):
特写_某人_ arr。追加(CSV _ rd。loc[I,](j))
特征_已知_排列。追加(features _ someone _ arr)
打印('数据库中的面孔:',len(features_known_arr))
# Dlib检测器和预测器
#将使用检测器和预测器
检测器=dlib。get _ frontier _ face _ detector()
预测值=dlib。shape _ predictor(' D:/no1 workspace/JupyterNotebook/model/shape _ predictor _ 68 _ face _ landmarks。dat’)
# 创建cv2摄像头对象
# cv2 .视频捕获(0)使用电脑的默认摄像头,
#您可以通过cv2使用本地视频名称。视频捕获(文件名)
cap=cv2 .视频捕获(0)
# cap.set(propId,value)
# 设置视频参数,propId设置的视频参数,值设置的参数值
第一套(3480英镑)
# cap.isOpened()返回对/错检查初始化是否成功
#当相机打开时
while cap.isOpened():
flag,img_rd=cap.read()
kk=cv2.waitKey(1)
# 取灰度
img_gray=cv2.cvtColor(img_rd,cv2 .彩色_ RGB 2灰色)
# 人脸数表面
faces=detector(img_gray,0)
# 待会要写的字体稍后要写的字体
font=cv2 .FONT _ HERSHEY _复杂
# 存储当前摄像头中捕获到的所有人脸的坐标/名字
#保存当前捕获的人脸的位置和名称的列表
pos_namelist=[]
name_namelist=[]
# 按下q键退出
#按"问"退出
如果kk==ord('q '):
破裂
否则:
# 检测到人脸当检测到人脸时
如果len(脸)!=0:
# 获取当前捕获到的图像的所有人脸的特征,存储到功能_cap_arr
#获取捕获的特征并保存到功能_cap_arr中
features_cap_arr=[]
对于范围内的我(透镜(面)):
形状=预测值(img_rd,faces[i])
功能_ cap _ arr。追加(facerec。compute _ face _ descriptor(img _ rd,shape))
# 遍历捕获到的图像中所有的人脸
#遍历数据库中的所有面
对于范围内的k(透镜(面)):
打印(' #####摄像人,k 1,' ##### ')
# 让人名跟随在矩形框的下方
# 确定人名的位置坐标
# 先默认所有人不认识,是未知的
#用"未知"设置面孔的默认名称
name_namelist.append('unknown ')
# 每个捕获人脸的名字坐标捕捉到的人脸位置
pos _ name列表。append(元组([faces[k].left(),int(faces[k]).bottom() (faces[k].bottom() - faces[k].top())/4)])
# 对于某张人脸,遍历所有存储的人脸特征
#对于每个检测到的人脸,比较数据库中的人脸
e_distance_list=[]
对于范围内的I(len(features _ known _ arr)):
# 如果人_X数据不为空
if str(features_known_arr[i][0])!='0.0':
print('与人',str(i 1),' e distance:',end=' ')
e _ distance _ tmp=return _ Euclid _ distance(features _ cap _ arr[k],features_known_arr[i])
打印(远程时间)
e _距离_列表.追加
否则:
# 空数据人_X
电子商务距离_列表。追加(99999999)
# 找出最接近的一个人脸数据是第几个
#找到e距离最小的一个
相似的人数=距离列表。索引(min(e _ distance _ list))
打印('与人的最小e距离,int(similar_person_num) 1)
# 计算人脸识别特征与数据集特征的欧氏距离
# 距离小于0.4则标出为可识别人物
如果最小值(电子距离列表)为0.4:
# 这里可以修改摄像头中标出的人名
#您可以在这里修改摄像机上显示的名称
# 1、遍历文件夹目录
folder _ name=' D:/no1 workspace/JupyterNotebook/Facetrainset/'
# 最接近的人脸
sum=similar_person_num 1
key_id=1 #从第一个人脸数据文件夹进行对比
# 获取文件夹中的文件名:1王、2周、3.
文件名=os.listdir(文件夹名)
对于文件名中的名称:
# print(name '-' str(key_id))
如果总和==关键字标识:
#winsound .哔声(300,500)#响铃:300频率,500持续时间
名称名称列表[k]=名称[1:]#人名删去第一个数字(用于视频输出标识)
key_id=1
# 播放欢迎光临音效
# playsound(' D:/我的工作区/JupyterNotebook/People/music/welcome。wav’)
#打印('可能是人'字符串(int(similar_person_num) 1))
# - 筛选出人脸并保存到访问者文件夹-
对于我,d在枚举(面):
x1=d.top() if d.top() 0 else 0
y1=d . bottom()if d . bottom()0 else 0
x2=d.left() if d.left() 0 else 0
y2=d.right() if d.right() 0 else 0
face=img_rd[x1:y1,x2:y2]
尺寸=64
face=cv2.resize(face,(size,size))
# 要存储访问者人脸图像文件的路径
path _ visitors _ save _ dir=' D:/no 1 workspace/JupyterNotebook/KnownFacetrainset/'
# 存储格式:2019-06-24-14-33-40王。使用jpeg文件交换格式存储的编码图像文件扩展名
now _ time=时间。strftime(' % Y-% M-% d-% H-% M-% S ',time.localtime())
save _ name=str(now _ time)str(name _ name list[k]).' jpg '
#打印(保存名称)
# 本次图片保存的完整全球资源定位器(统一资源定位器)
保存路径=路径访问者保存目录'/'保存名称
# 遍历访问者文件夹所有文件名
访问者姓名=操作系统。列表目录(路径_访问者_保存_目录)
visitor_name=' '
对于访问者姓名中的姓名:
# 名字切片到分钟数:2019-06-26-11-33-00wangyu.jpg
visitor _ name=(name[0:16]'-00 ' name[19:])
#打印(访问者姓名)
visitor _ save=(save _ name[0:16]'-00 ' save _ name[19:])
#打印(访问者_保存)
# 一分钟之内重复的人名不保存
如果访问者_保存!=访问者姓名:
cv2.imwrite(保存路径,面)
打印('新存储:'路径访问者保存目录/' str(now _ time)str(name _ name list[k])' .jpg’)
否则:
打印('重复,未保存!')
否则:
# 播放无法识别音效
# playsound(' D:/我的工作区/JupyterNotebook/People/music/抱歉。wav’)
打印("未知人员")
# - 保存图片-
# - 筛选出人脸并保存到访问者文件夹-
对于我,d在枚举(面):
x1=d.top() if d.top() 0 else 0
y1=d . bottom()if d . bottom()0 else 0
x2=d.left() if d.left() 0 else 0
y2=d.right() if d.right() 0 else 0
face=img_rd[x1:y1,x2:y2]
尺寸=64
face=cv2.resize(face,(size,size))
# 要存储访客-》未知人脸图像文件的路径
path _ visitors _ save _ dir=' D:/no1 workspace/JupyterNotebook/unknown facetrainset/'
# 存储格式:2019-06-24-14-33-40未知。使用jpeg文件交换格式存储的编码图像文件扩展名
now _ time=时间。strftime(' % Y-% M-% d-% H-% M-% S ',time.localtime())
#打印(保存名称)
# 本次图片保存的完整全球资源定位器(统一资源定位器)
save _ path=path _ visitors _ save _ dir '/' str(now _ time)'未知。' jpg '
cv2.imwrite(保存路径,面)
打印('新存储:' path _ visitors _ save _ dir '/' str(now _ time)'未知。jpg’)
# 矩形框
#绘制矩形
对于kk,d在枚举(面):
# 绘制矩形框
cv2.rectangle(img_rd,tuple([d.left(),d.top()]),tuple([d.right(),d.bottom()]),(0,255,255),2)
打印(' \n ')
# 在人脸框下面写人脸名字
#在矩形下写名字
对于范围内的我(透镜(面)):
cv2.putText(img_rd,name_namelist[i],pos_namelist[i],font,0.8,(0,255,255),1,cv2 .LINE_AA)
打印('现在相机中的面孔:',name_namelist,' \n ')
#cv2.putText(img_rd,'按q': Quit ',(20,450),font,0.8,(84,255,159),1,cv2 .LINE_AA)
cv2.putText(img_rd,'人脸识别,(20,40),font,1,(0,0,255),1,cv2 .LINE_AA)
cv2.putText(img_rd,' Visitors: ' str(len(faces)),(20,100),font,1,(0,0,255),1,cv2 .LINE_AA)
# 窗口显示用opencv显示
cv2.imshow('camera ',img_rd)
# 释放摄像头释放摄像机
cap.release()
# 删除建立的窗口删除所有窗口
cv2.destroyAllWindows()
若直接使用本代码,文件目录弄成中文会乱码
运行效果:
没有吴京叔叔的数据集,所以他是陌生人
到此这篇关于计算机编程语言实现人脸识别的文章就介绍到这了,更多相关计算机编程语言人脸识别内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。