0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Dlib人脸特征检测原理

新机器视觉 来源:python专栏 作者:python专栏 2022-09-06 15:48 次阅读

使用到的库:dlib+Opencvpython版本:3.8编译环境:Jupyter Notebook (Anaconda3)

0.Dlib人脸特征检测原理

提取特征点:请参考

首选抓取多张图片,从中获取特征数据集和平均特征值然后写入csv文件 - 计算特征数据集的欧式距离作对比:首先使用Opencv库将摄像头中的人脸框出来,再将摄像头中采取到的人脸特征值与数据集中的每个人的特征均值作对比,选取最接近(欧氏距离最小)的值,将其标注为欧氏距离最小的数据集的人名

1735dc42-2b8e-11ed-ba43-dac502259ad0.png

一、构建人脸特征数据集

1、安装Dlib

请参考

2、构建自己的数据集

2.1 抓取人脸图片

17514086-2b8e-11ed-ba43-dac502259ad0.png

视频流中抓取人脸特征,并保存为256*256大小的图片文件共20张,这就是我们建立数据集的第一步,用来训练人脸识别。

“不一定是256*256的尺寸,可以根据自己的需求来调整大小,图片越大训练结果会愈加精确,但也会影响训练模型的时间。

其中:

光线:曝光和黑暗的图片需手动剔除- 请使用同一个设备进行数据采集,不同设备的摄像头采集到的数据集会有出入- 这里采用的是从视频流中进行捕捉截图,也可以自己准备20张左右的人脸图片

代码:

importcv2
importdlib
importos
importsys
importrandom
#存储位置
output_dir='D:/No1WorkSpace/JupyterNotebook/Facetrainset/Num&Name'#这里填编号+人名
size=256#图片边长

ifnotos.path.exists(output_dir):
os.makedirs(output_dir)
#改变图片的亮度与对比度

defrelight(img,light=1,bias=0):
w=img.shape[1]
h=img.shape[0]
#image=[]
foriinrange(0,w):
forjinrange(0,h):
forcinrange(3):
tmp=int(img[j,i,c]*light+bias)
iftmp>255:
tmp=255
eliftmp<0:
tmp=0
img[j,i,c]=tmp
returnimg

#使用dlib自带的frontal_face_detector作为我们的特征提取器
detector=dlib.get_frontal_face_detector()
#打开摄像头参数为输入流,可以为摄像头或视频文件
camera=cv2.VideoCapture(0)
#camera=cv2.VideoCapture('C:/Users/CUNGU/Videos/Captures/wang.mp4')

index=1
whileTrue:
if(index<=20):#存储15张人脸特征图像
print('Beingprocessedpicture%s'%index)
#从摄像头读取照片
success,img=camera.read()
#转为灰度图片
gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#使用detector进行人脸检测
dets=detector(gray_img,1)

fori,dinenumerate(dets):
x1=d.top()ifd.top()>0else0
y1=d.bottom()ifd.bottom()>0else0
x2=d.left()ifd.left()>0else0
y2=d.right()ifd.right()>0else0

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.imwrite(output_dir+'/'+str(index)+'.jpg',face)

index+=1
key=cv2.waitKey(30)&0xff
ifkey==27:
break
else:
print('Finished!')
#释放摄像头releasecamera
camera.release()
#删除建立的窗口deleteallthewindows
cv2.destroyAllWindows()
break

运行效果:

176d74fe-2b8e-11ed-ba43-dac502259ad0.jpg

2.2 分析每张人脸的特征值并存入csv文件

根据抓取的图片和人脸识别模型->训练得到的20个的68个特征数据集以及1个平均特征值存入csv文件

“每张图片的68个特征数据集可以不用存取,他们只是中间量,计算平均值以后就可以抛弃了,这里把他们输出出来只是为了方便学习。

代码:

#从人脸图像文件中提取人脸特征存入CSV
#Featuresextractionfromimagesandsaveintofeatures_all.csv

#return_128d_features()获取某张图像的128D特征
#compute_the_mean()计算128D特征均值

fromcv2importcv2ascv2
importos
importdlib
fromskimageimportio
importcsv
importnumpyasnp

#要读取人脸图像文件的路径
path_images_from_camera="D:/No1WorkSpace/JupyterNotebook/Facetrainset/"

#Dlib正向人脸检测器
detector=dlib.get_frontal_face_detector()

#Dlib人脸预测器
predictor=dlib.shape_predictor("D:/No1WorkSpace/JupyterNotebook/model/shape_predictor_68_face_landmarks.dat")

#Dlib人脸识别模型
#Facerecognitionmodel,theobjectmapshumanfacesinto128Dvectors
face_rec=dlib.face_recognition_model_v1("D:/No1WorkSpace/JupyterNotebook/model/dlib_face_recognition_resnet_model_v1.dat")


#返回单张图像的128D特征
defreturn_128d_features(path_img):
img_rd=io.imread(path_img)
img_gray=cv2.cvtColor(img_rd,cv2.COLOR_BGR2RGB)
faces=detector(img_gray,1)

print("%-40s%-20s"%("检测到人脸的图像/imagewithfacesdetected:",path_img),'
')

#因为有可能截下来的人脸再去检测,检测不出来人脸了
#所以要确保是检测到人脸的人脸图像拿去算特征
iflen(faces)!=0:
shape=predictor(img_gray,faces[0])
face_descriptor=face_rec.compute_face_descriptor(img_gray,shape)
else:
face_descriptor=0
print("noface")

returnface_descriptor


#将文件夹中照片特征提取出来,写入CSV
defreturn_features_mean_personX(path_faces_personX):
features_list_personX=[]
photos_list=os.listdir(path_faces_personX)
ifphotos_list:
foriinrange(len(photos_list)):
withopen("D:/No1WorkSpace/JupyterNotebook/feature/featuresGiao"+str(i)+".csv","w",newline="")ascsvfile:
writer=csv.writer(csvfile)
#调用return_128d_features()得到128d特征
print("%-40s%-20s"%("正在读的人脸图像/imagetoread:",path_faces_personX+"/"+photos_list[i]))
features_128d=return_128d_features(path_faces_personX+"/"+photos_list[i])
print(features_128d)
writer.writerow(features_128d)
#遇到没有检测出人脸的图片跳过
iffeatures_128d==0:
i+=1
else:
features_list_personX.append(features_128d)
else:
print("文件夹内图像文件为空/Warning:Noimagesin"+path_faces_personX+'/','
')

#计算128D特征的均值
#Nx128D->1x128D
iffeatures_list_personX:
features_mean_personX=np.array(features_list_personX).mean(axis=0)
else:
features_mean_personX='0'

returnfeatures_mean_personX


#读取某人所有的人脸图像的数据
people=os.listdir(path_images_from_camera)
people.sort()

withopen("D:/No1WorkSpace/JupyterNotebook/feature/features_all.csv","w",newline="")ascsvfile:
writer=csv.writer(csvfile)
forpersoninpeople:
print("#####"+person+"#####")
#Getthemean/averagefeaturesofface/personX,itwillbealistwithalengthof128D
features_mean_personX=return_features_mean_personX(path_images_from_camera+person)
writer.writerow(features_mean_personX)
print("特征均值/Themeanoffeatures:",list(features_mean_personX))
print('
')
print("所有录入人脸数据存入/Saveallthefeaturesoffacesregisteredinto:D:/myworkspace/JupyterNotebook/People/feature/features_all2.csv")

“如果要输出每一张图片的特征数据集,这里要用到Python的文件批量生成。

代码运行效果

17a16bc4-2b8e-11ed-ba43-dac502259ad0.jpg

17c55cf0-2b8e-11ed-ba43-dac502259ad0.jpg

17e0fc80-2b8e-11ed-ba43-dac502259ad0.jpg

二、识别人脸并匹配数据集

1、原理:

通过计算特征数据集的欧氏距离作对比来识别人脸,取欧氏距离最小的数据集进行匹配。

“欧氏距离也称欧几里得距离或欧几里得度量,是一个通常采用的距离定义,它是在m维空间中两个点之间的真实距离。在二维和三维空间中的欧氏距离的就是两点之间的距离。使用这个距离,欧氏空间成为度量空间。相关联的范数称为欧几里得范数。较早的文献称之为毕达哥拉斯度量。二维空间公式:

1813af22-2b8e-11ed-ba43-dac502259ad0.png

1825a790-2b8e-11ed-ba43-dac502259ad0.png

2、视频流实时识别人脸数据

代码:

#摄像头实时人脸识别
importos
importdlib#人脸处理的库Dlib
importcsv#存入表格
importtime
importsys
importnumpyasnp#数据处理的库numpy
fromcv2importcv2ascv2#图像处理的库OpenCv
importpandasaspd#数据处理的库Pandas


#人脸识别模型,提取128D的特征矢量
#facerecognitionmodel,theobjectmapshumanfacesinto128Dvectors
#Referthistutorial:http://dlib.net/python/index.html#dlib.face_recognition_model_v1
facerec=dlib.face_recognition_model_v1("D:/No1WorkSpace/JupyterNotebook/model/dlib_face_recognition_resnet_model_v1.dat")


#计算两个128D向量间的欧式距离
#computethee-distancebetweentwo128Dfeatures
defreturn_euclidean_distance(feature_1,feature_2):
feature_1=np.array(feature_1)
feature_2=np.array(feature_2)
dist=np.sqrt(np.sum(np.square(feature_1-feature_2)))
returndist


#处理存放所有人脸特征的csv
path_features_known_csv="D:/No1WorkSpace/JupyterNotebook/feature/features_all.csv"
csv_rd=pd.read_csv(path_features_known_csv,header=None)


#用来存放所有录入人脸特征的数组
#thearraytosavethefeaturesoffacesinthedatabase
features_known_arr=[]

#读取已知人脸数据
#printknownfaces
foriinrange(csv_rd.shape[0]):
features_someone_arr=[]
forjinrange(0,len(csv_rd.loc[i,:])):
features_someone_arr.append(csv_rd.loc[i,:][j])
features_known_arr.append(features_someone_arr)
print("Faces in Database:",len(features_known_arr))

#Dlib检测器和预测器
#Thedetectorandpredictorwillbeused
detector=dlib.get_frontal_face_detector()
predictor=dlib.shape_predictor('D:/No1WorkSpace/JupyterNotebook/model/shape_predictor_68_face_landmarks.dat')

#创建cv2摄像头对象
#cv2.VideoCapture(0)tousethedefaultcameraofPC,
#andyoucanuselocalvideonamebyusecv2.VideoCapture(filename)
cap=cv2.VideoCapture(0)

#cap.set(propId,value)
#设置视频参数,propId设置的视频参数,value设置的参数值
cap.set(3,480)

#cap.isOpened()返回true/false检查初始化是否成功
#whenthecameraisopen
whilecap.isOpened():

flag,img_rd=cap.read()
kk=cv2.waitKey(1)

#取灰度
img_gray=cv2.cvtColor(img_rd,cv2.COLOR_RGB2GRAY)

#人脸数faces
faces=detector(img_gray,0)

#待会要写的字体fonttowritelater
font=cv2.FONT_HERSHEY_COMPLEX

#存储当前摄像头中捕获到的所有人脸的坐标/名字
#thelisttosavethepositionsandnamesofcurrentfacescaptured
pos_namelist=[]
name_namelist=[]

#按下q键退出
#press'q'toexit
ifkk==ord('q'):
break
else:
#检测到人脸whenfacedetected
iflen(faces)!=0:
#获取当前捕获到的图像的所有人脸的特征,存储到features_cap_arr
#getthefeaturescapturedandsaveintofeatures_cap_arr
features_cap_arr=[]
foriinrange(len(faces)):
shape=predictor(img_rd,faces[i])
features_cap_arr.append(facerec.compute_face_descriptor(img_rd,shape))

#遍历捕获到的图像中所有的人脸
#traversalallthefacesinthedatabase
forkinrange(len(faces)):
print("#####cameraperson",k+1,"#####")
#让人名跟随在矩形框的下方
#确定人名的位置坐标
#先默认所有人不认识,是unknown
#setthedefaultnamesoffaceswith"unknown"
name_namelist.append("unknown")

#每个捕获人脸的名字坐标thepositionsoffacescaptured
pos_namelist.append(tuple([faces[k].left(),int(faces[k].bottom()+(faces[k].bottom()-faces[k].top())/4)]))

#对于某张人脸,遍历所有存储的人脸特征
#foreveryfacesdetected,comparethefacesinthedatabase
e_distance_list=[]
foriinrange(len(features_known_arr)):
#如果person_X数据不为空
ifstr(features_known_arr[i][0])!='0.0':
print("withperson",str(i+1),"theedistance:",end='')
e_distance_tmp=return_euclidean_distance(features_cap_arr[k],features_known_arr[i])
print(e_distance_tmp)
e_distance_list.append(e_distance_tmp)
else:
#空数据person_X
e_distance_list.append(999999999)
#找出最接近的一个人脸数据是第几个
#Findtheonewithminimumedistance
similar_person_num=e_distance_list.index(min(e_distance_list))
print("Minimumedistancewithperson",int(similar_person_num)+1)

#计算人脸识别特征与数据集特征的欧氏距离
#距离小于0.4则标出为可识别人物
ifmin(e_distance_list)<0.4:
#这里可以修改摄像头中标出的人名
#Hereyoucanmodifythenamesshownonthecamera
#1、遍历文件夹目录
folder_name='D:/No1WorkSpace/JupyterNotebook/Facetrainset/'
#最接近的人脸
sum=similar_person_num+1
key_id=1#从第一个人脸数据文件夹进行对比
#获取文件夹中的文件名:1wang、2zhou、3...
file_names=os.listdir(folder_name)
fornameinfile_names:
#print(name+'->'+str(key_id))
ifsum==key_id:
#winsound.Beep(300,500)#响铃:300频率,500持续时间
name_namelist[k]=name[1:]#人名删去第一个数字(用于视频输出标识)
key_id+=1
#播放欢迎光临音效
#playsound('D:/myworkspace/JupyterNotebook/People/music/welcome.wav')
#print("Maybeperson"+str(int(similar_person_num)+1))
#-----------筛选出人脸并保存到visitor文件夹------------
fori,dinenumerate(faces):
x1=d.top()ifd.top()>0else0
y1=d.bottom()ifd.bottom()>0else0
x2=d.left()ifd.left()>0else0
y2=d.right()ifd.right()>0else0
face=img_rd[x1:y1,x2:y2]
size=64
face=cv2.resize(face,(size,size))
#要存储visitor人脸图像文件的路径
path_visitors_save_dir="D:/No1WorkSpace/JupyterNotebook/KnownFacetrainset/"
#存储格式:2019-06-24-14-33-40wang.jpg 
now_time=time.strftime("%Y-%m-%d-%H-%M-%S",time.localtime())
save_name=str(now_time)+str(name_namelist[k])+'.jpg'
#print(save_name)
#本次图片保存的完整url
save_path=path_visitors_save_dir+'/'+save_name
#遍历visitor文件夹所有文件名
visitor_names=os.listdir(path_visitors_save_dir)
visitor_name=''
fornameinvisitor_names:
#名字切片到分钟数:2019-06-26-11-33-00wangyu.jpg 
visitor_name=(name[0:16]+'-00'+name[19:])
#print(visitor_name)
visitor_save=(save_name[0:16]+'-00'+save_name[19:])
#print(visitor_save)
#一分钟之内重复的人名不保存
ifvisitor_save!=visitor_name:
cv2.imwrite(save_path,face)
print('新存储:'+path_visitors_save_dir+'/'+str(now_time)+str(name_namelist[k])+'.jpg')
else:
print('重复,未保存!')

else:
#播放无法识别音效
#playsound('D:/myworkspace/JupyterNotebook/People/music/sorry.wav')
print("Unknownperson")
#-----保存图片-------
#-----------筛选出人脸并保存到visitor文件夹------------
fori,dinenumerate(faces):
x1=d.top()ifd.top()>0else0
y1=d.bottom()ifd.bottom()>0else0
x2=d.left()ifd.left()>0else0
y2=d.right()ifd.right()>0else0
face=img_rd[x1:y1,x2:y2]
size=64
face=cv2.resize(face,(size,size))
#要存储visitor-》unknown人脸图像文件的路径
path_visitors_save_dir="D:/No1WorkSpace/JupyterNotebook/UnKnownFacetrainset/"
#存储格式:2019-06-24-14-33-40unknown.jpg 
now_time=time.strftime("%Y-%m-%d-%H-%M-%S",time.localtime())
#print(save_name)
#本次图片保存的完整url
save_path=path_visitors_save_dir+'/'+str(now_time)+'unknown.jpg'
cv2.imwrite(save_path,face)
print('新存储:'+path_visitors_save_dir+'/'+str(now_time)+'unknown.jpg')

#矩形框
#drawrectangle
forkk,dinenumerate(faces):
#绘制矩形框
cv2.rectangle(img_rd,tuple([d.left(),d.top()]),tuple([d.right(),d.bottom()]),(0,255,255),2)
print('
')

#在人脸框下面写人脸名字
#writenamesunderrectangle
foriinrange(len(faces)):
cv2.putText(img_rd,name_namelist[i],pos_namelist[i],font,0.8,(0,255,255),1,cv2.LINE_AA)

print("Facesincameranow:",name_namelist,"
")

#cv2.putText(img_rd,"Press'q':Quit",(20,450),font,0.8,(84,255,159),1,cv2.LINE_AA)
cv2.putText(img_rd,"FaceRecognition",(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)

#窗口显示showwithopencv
cv2.imshow("camera",img_rd)

#释放摄像头releasecamera
cap.release()

#删除建立的窗口deleteallthewindows
cv2.destroyAllWindows()

“若直接使用本代码,文件目录弄成中文会乱码

图中两人的特征数据集均已被收集并录入,所以可以识别出来,如果没有被录入的人脸就会出现unknown。

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 摄像头
    +关注

    关注

    59

    文章

    4790

    浏览量

    95244
  • 编译
    +关注

    关注

    0

    文章

    648

    浏览量

    32764
  • OpenCV
    +关注

    关注

    29

    文章

    624

    浏览量

    41206

原文标题:手把手教你运用Python实现进阶版人脸识别

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    在Python中利用dlib进行人脸检测

    Dlib是一个现代化的C ++工具包,包含用于创建复杂软件的机器学习算法和工具”。它使您能够直接在Python中运行许多任务,其中一个例子就是人脸检测
    发表于 05-10 03:56 6545次阅读
    在Python中利用<b class='flag-5'>dlib</b>进行<b class='flag-5'>人脸</b><b class='flag-5'>检测</b>

    基于matlab的人脸检测K-L的人脸识别(肤色分割和特征提取)

    基于matlab的人脸检测K-L的人脸识别(肤色分割和特征提取)[hide] [/hide]《labview人脸识别》课程链接:http:/
    发表于 02-22 16:45

    matlab毕业论文-快速人脸特征定位

    的完成涉及从复杂的背景中分割、抽取、验证人脸区域和可能用到的人脸特征(如眼睛、唇色等)。成功的人脸检测系统应能处理实际存在的光线、
    发表于 03-07 10:22

    人脸检测跟踪与特征点定位系统

    人脸检测跟踪与特征点定位系统
    发表于 08-06 13:07

    人脸检测算法及新的快速算法

    最近几年的人脸检测算法和一种新的快速算法,与大家探讨特征、弱分类器、收敛准则、样本选择等对人脸检测性能的影响,并尝试分析
    发表于 09-26 15:13

    基于层次型AdaBoost检测算法的快速人脸检测该怎么实现?

    人脸检测是指对于给定的图像或视频,判断其中是否存在人脸,如果存在,则进一步确定人脸的个数、具体位置以及大小的过程。作为一个模式识别问题,人脸
    发表于 09-02 07:49

    【米尔FZ3深度学习计算卡免费试用】+疲劳驾驶检测系统第二部分眼睛状态识别

    速度变慢)、点头(瞌睡点头),可以根据这些特点进行疲劳驾驶检测。第一人脸特征点提取采用dlib实现人脸
    发表于 01-10 18:24

    如何利用Haar Cascade特征检测器来实现人脸检测

    怎样采用LBP特征进行人脸检测人脸识别呢?如何利用Haar Cascade特征检测器来实现
    发表于 02-28 08:20

    基于肤色模型和区域特征人脸检测方法

    精度和速度是人脸检测系统的两个衡量标准。针对传统人脸检测方法两者不能兼优的问题,该文提出一种结合颜色空间和特征区域的
    发表于 04-15 08:55 25次下载

    基于几何特征与新Haar特征人脸检测算法_糜元根

    基于几何特征与新Haar特征人脸检测算法_糜元根
    发表于 03-19 19:25 2次下载

    如何用40行代码实现人脸识别?

    Dlib里面有人脸检测器,有训练好的人脸关键点检测器,也有训练好的人脸识别模型。
    的头像 发表于 07-15 09:16 4739次阅读

    这就是你需要的人脸特征检测方法

    它的训练方法类似于Dlib的68个面部特征点形状预测器。只是在原有的68个特征点的基础上,在额头区域增加了13个点。这就使得头部的检测,以及用于需要沿着头部顶部的点的图像操作更加精准。
    的头像 发表于 03-19 09:35 7086次阅读

    基于特征图融合的小尺寸人脸检测方法

    人脸检测是指从输入图片或视频中找到人脸的精确位置并确定其大小。为了应对尺度多样性特别是小尺寸人脸人脸
    发表于 05-29 14:17 10次下载

    DCNN网络结构 DCNN的人脸特征检测

    摘 要:在介绍人脸特征检测的理论知识的基础上,提出了一种基于深层卷积神经网络(Deep ConvolutionalNeural Network,DCNN)解决人脸5点
    发表于 07-20 14:30 0次下载

    人脸检测的五种方法各有什么特征和优缺点

    人脸检测是计算机视觉领域的一个重要研究方向,主要用于识别和定位图像中的人脸。以下是五种常见的人脸检测方法及其
    的头像 发表于 07-03 14:47 590次阅读