Python与人工智能入门实践——简易人脸识别系统

写在前面:

笔者在寒假期间进行了一些简短的实训,主要内容包括简单的爬虫和简单的人脸识别算法,由于时间有限,对于python也是第一次详细学习,功能较为简单,提供给入学者参考,帮助大家进入py的世界,若有不正确或不明确的地方欢迎指正。

一、相关包和工具的安装

人脸识别所需要的包有:

dlib

opencv

numpy

pandas

pillow

为了方便安装可以从网上下载.whl文件,安装过程省去了联网下载的过程

另外建立可视化界面这里用到的是tkinter包

tkinter包中主要提供了一些按钮、文字等功能,类似于java中的swing

另外用到了两个文件是

这两个是已经训练好了人脸识别模型和人脸68个关键点位置提取

二、编写代码

主要功能是用户注册时拍照抓取人脸,在登录时重新拍照验证是否与已注册用户相匹配

1.建立项目

主要包括一下文件

2.data包中的主要功能是保存用户数据和判断是否是同一个人,利用两个图像的欧氏距离,若小于0.35则找到匹配对象

data_util.py
import pickle
import numpy# 保存用户数据到文件中
def save(user_info):# 以追加二进制的方式打开一个文件file = open("userInfo.dat", 'ab')# 使用pickle将user_info对象写入到文件中pickle.dump(user_info, file)file.close()
def read():#以二进制的方式读取一个文件file = open("userInfo.dat", 'rb')#将文件中的二进制还原回对象ls=[]while True:try:user_info=pickle.load(file)ls.append(user_info)except:breakfile.close()return ls
# 从文件中查询用户数据
def query(face):ls=read()for user_info in ls:user_face=user_info.face#计算user_face与face之间的欧氏距离#将128维向量转成矩阵old_face=numpy.array(user_face)new_face=numpy.array(face)dist=numpy.sqrt(numpy.sum(numpy.square(old_face-new_face)))if dist<0.35:return user_info

user_info.py

#描述用户信息
class UserInfo():def __init__(self,name,face):self.name=nameself.face=face

3.utils包主要是调用摄像头进行拍照与图片处理

camera.py

import cv2
import copy
def get_photo():try:#VideoCapture打开一个视频,filename   0:打开默认摄像头cap=cv2.VideoCapture(0)#读取一个图片出来font=cv2.FONT_HERSHEY_COMPLEXwhile True:flag,photo=cap.read()#深度拷贝photo2=copy.deepcopy(photo)#在窗口绘制文本cv2.putText(photo, "Press space to take photos", (20,40), font, 1, (0,255,0))#img, text(中文不能正常显示), org, fontFace(定义的FONT_HERSHEY_COMPLEX), fontScale(行距), color,#显示图片cv2.imshow('Camera',photo)key=cv2.waitKey(1)if key==ord(' '):#转成asc码进行检测才可以cap.release()cv2.destroyAllWindows()return photo2except:return None
if __name__ == '__main__':get_photo()

img_handle.py

import dlib
import cv2
import os
#图像处理类
class ImgHandle():def __init__(self):#获取正面人脸检测器self.detector=dlib.get_frontal_face_detector()# 人脸68特征点predictor_path = 'shape_predictor_68_face_landmarks.dat'self.sp = dlib.shape_predictor(predictor_path)# 128D 向量生成器face_rec_model_path = 'dlib_face_recognition_resnet_model_v1.dat'self.facerec = dlib.face_recognition_model_v1(face_rec_model_path)def get_handle(self,img):#检测图片中的人脸区域,返回值为图片中检测到人脸的区域,可能有多个dets=self.detector(img,1)#如果处理过程过慢,可以将1->0,或者用cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)将图片改成灰度图以提高效率#判断人脸数量if len(dets)==1:for det in dets:# print(det.top())# print(det.bottom())# print(det.left())# print(det.right())#图片坐标cv2.rectangle(img,(det.left(),det.top()),(det.right(),det.bottom()),(255,0,0))#在图片上绘制矩形区域#调用检测器提取68个特征点shape=self.sp(img,det)count = 1for pt in shape.parts():cv2.circle(img,(pt.x,pt.y,),2,(0,0,255))cv2.putText(img,str(count),(pt.x,pt.y),cv2.FONT_HERSHEY_PLAIN,0.5,(0,255,0))count+=1face_descriptor=self.facerec.compute_face_descriptor(img,shape)#print(face_descriptor)return face_descriptorelse:return None

4.view包主要利用tkinter设计简单的界面

login_frame.py

import tkinter
from tkinter import messagebox
import numpy
import cv2
from PIL import ImageTk, Image
from utils.camera import get_photo
from utils.img_handle import ImgHandle
from data.data_util import query
class LoginFrame(tkinter.Frame):def __init__(self, master=None, root=None):super().__init__(master=master, bg='yellow')self.root = rootbtn_back = tkinter.Button(master=self, text='返回', command=self.btn_back_click)btn_back.place(x=20, y=30, width=80, height=40)btn_pic = tkinter.Button(master=self, text='拍照', command=self.btn_pic_click)btn_pic.place(x=20, y=90, width=80, height=40)btn_save = tkinter.Button(master=self, text='验证', command=self.btn_save_click)btn_save.place(x=20, y=150, width=80, height=40)self.lab = tkinter.Label(self)self.lab.place(x=120, y=20)self.face = Nonedef btn_back_click(self):self.root.show_frm('main')def btn_pic_click(self):photo = get_photo()if isinstance(photo, numpy.ndarray):img_handle = ImgHandle()self.face = img_handle.get_handle(photo)if self.face == None:messagebox.showinfo('提示', '人脸检测失败,请确保拍照时有且仅有一个人')else:# 转换颜色通道rgb_photo = cv2.cvtColor(photo, cv2.COLOR_BGR2RGB)# 显示图片# 图片格式转换,从opencv的矩阵格式转换成Tk中的位图格式img = Image.fromarray(rgb_photo)img_tk = ImageTk.PhotoImage(image=img)# 将图片设置给labelself.lab.imgtk = img_tkself.lab.config(image=img_tk)else:messagebox.showinfo('提示', '图片抓取失败!请检查您的摄像头是否可用。')def btn_save_click(self):if self.face==None:messagebox.showinfo('提示', '请先拍照')else:user_info=query(self.face)if user_info!=None:messagebox.showinfo('登录成功', '欢迎'+user_info.name+'进入系统')else:messagebox.showinfo('登录失败', '请确认是否是合法用户或者调整拍照角度重新拍照')

main_frame.py

import tkinter
import tkinter.font
class MainFrame(tkinter.Frame):def __init__(self, master=None, root=None):super().__init__(master=master)self.root = rootfont = tkinter.font.Font(size=20,family="楷体")lab=tkinter.Label(master=self,text='欢迎使用ST人脸识别系统',font=font,foreground="red")lab.pack(pady=50)#font_login = tkinter.font.Font(size=30)btn_reg = tkinter.Button(master=self, text='注册', command=self.btn_reg_click,font=font,bg="red")btn_reg.pack(pady=30,ipady=30,ipadx=150)btn_login = tkinter.Button(master=self, text='登录', command=self.btn_login_click,font=font,bg="blue")btn_login.pack(pady=30,ipady=30,ipadx=150)def btn_reg_click(self):self.root.show_frm('reg')def btn_login_click(self):self.root.show_frm('login')

reg_frame.py

import tkinter
import numpy
from tkinter import messagebox
from utils.camera import get_photo
from PIL import Image,ImageTk
from tkinter.simpledialog import askstring
import cv2
from utils.img_handle import ImgHandle
import data.user_info
from data.user_info import UserInfo
import data.data_util
class RegFrame(tkinter.Frame):def __init__(self, master=None, root=None):super().__init__(master=master)self.root = rootbtn_back = tkinter.Button(master=self, text='返回', command=self.btn_back_click)btn_back.place(x=20, y=30, width=80, height=40)btn_pic = tkinter.Button(master=self, text='拍照', command=self.btn_pic_click)btn_pic.place(x=20, y=90, width=80, height=40)btn_save = tkinter.Button(master=self, text='保存', command=self.btn_save_click)btn_save.place(x=20, y=150, width=80, height=40)#label控件显示照片self.lab=tkinter.Label(self)self.lab.place(x=120, y=20)self.face=Nonedef btn_back_click(self):self.root.show_frm('main')def btn_pic_click(self):photo = get_photo()if isinstance(photo,numpy.ndarray):img_handle=ImgHandle()self.face=img_handle.get_handle(photo)if self.face==None:messagebox.showinfo('提示', '人脸检测失败,请确保拍照时有且仅有一个人')else:#转换颜色通道rgb_photo=cv2.cvtColor(photo,cv2.COLOR_BGR2RGB)#显示图片#图片格式转换,从opencv的矩阵格式转换成Tk中的位图格式img=Image.fromarray(rgb_photo)img_tk=ImageTk.PhotoImage(image=img)#将图片设置给labelself.lab.imgtk=img_tkself.lab.config(image=img_tk)else:messagebox.showinfo('提示', '图片抓取失败!请检查您的摄像头是否可用。')def btn_save_click(self):if self.face!=None:#获取姓名name=askstring('输入','请输入名字')if name==None:messagebox.showinfo('提示', '请输入姓名')else:user_info=UserInfo(name,self.face)data.data_util.save(user_info)passelse:messagebox.showinfo('提示', '请先拍照再保存')

main_win.py

# 主界面
import tkinter
from view.main_frame import MainFrame
from view.reg_frame import RegFrame
from view.login_frame import LoginFrame# 从Tk类派生出类MainWin ,
class MainWin(tkinter.Tk):# 重写构造方法def __init__(self):super().__init__()# 设置标题self.title('人脸识别登录系统')# 窗口大小和位置self.center()# Framecontainer = tkinter.Frame(self, bg='#FF0000')container.pack(fill=tkinter.BOTH, expand=True)container.rowconfigure(0, weight=1)container.columnconfigure(0, weight=1)# 将主Frame 添加到container中self.main_frm = MainFrame(container, self)self.main_frm.grid(row=0, column=0, sticky=tkinter.NSEW)# 将注册的Frame添加到container中self.reg_frm = RegFrame(container, self)self.reg_frm.grid(row=0, column=0, sticky=tkinter.NSEW)# 登录Frameself.login_frm = LoginFrame(container, self)self.login_frm.grid(row=0, column=0, sticky=tkinter.NSEW)self.show_frm('main')# 显示不同的Framedef show_frm(self, name):if name == 'main':self.main_frm.tkraise()elif name == 'reg':self.reg_frm.tkraise()else:self.login_frm.tkraise()def center(self):self.width = 800self.height = 600screen_width = self.winfo_screenwidth()screen_height = self.winfo_screenheight()x = (screen_width - self.width) // 2y = (screen_height - self.height) // 2self.geometry('%dx%d+%d+%d'%(self.width, self.height, x, y))if __name__ == '__main__':win = MainWin()win.mainloop()

三、操作过程

首先注册,空格键拍照,保存并输入名字,为了有助于学习,拍照出来的照片处理结果用蓝色矩形框选中了识别出来的人脸区域,68个特征点用绿色的数字标注出来。

返回主界面登录界面重新拍照,拍完后验证,若成功则显示欢迎xxx进入,失败会提示:请确认是否是合法用户或者调整拍照角度重新拍照。

最后希望这篇博客能够帮助各位完成人脸识别的基础入门( ̄▽ ̄)/

源码及包(训练数据.dat和.whl文件):

链接:https://pan.baidu.com/s/18X0NpJMgC5z1NJuSgrLf9g 
提取码:99ro

Python与人工智能入门实践——简易人脸识别系统相关推荐

  1. 人脸识别实践(2) - 人脸识别系统展示

    文章目录 写在前面 1. 人脸注册 2. 人脸更新 3. 人脸删除 4. 人脸库查询 5. 人脸识别 6. 扩展思考 写在前面   由于直接讲代码略显枯燥,遵循个人做事风格,先看整体效果,再进行细致了 ...

  2. 【AI达人创造营第三期】从零教你搭建基础人脸识别系统

    基于凌蒙派RK3568部署人脸识别系统 一.项目背景 (一).AIStudio方案调研 AIStudio中搜了一圈,和人脸识别系统有关的项目大致有两个类型,典型代表如下: 项目一: 人脸识别(3):部 ...

  3. OpenCV4.5.4 DNN人脸识别模块使用介绍--如何快速搭建一个人脸识别系统

    点击下方卡片,关注"OpenCV与AI深度学习" 视觉/图像重磅干货,第一时间送达 导读 本文主要介绍OpenCV4.5.4中人脸识别模块的使用和简易人脸识别系统的搭建,供大家参考 ...

  4. linux的系统监视器图片_用Nvidia Jetson Nano 2GB和Python构建一个价值60美元的人脸识别系统 - 人工智能遇见磐创...

    作者|Adam Geitgey 编译|Flin 来源|medium 新的Nvidia Jetson Nano 2GB开发板(今天宣布!)是一款单板机,售价59美元,运行带有GPU加速的人工智能软件. ...

  5. python怎么另起一行阅读答案_使用Python+Dlib构建人脸识别系统(在Nvidia Jetson Nano 2GB开发板上)...

    Nvidia Jetson Nano 2GB开发板是一款新的单板机 售价59美元 运行带有GPU加速的人工智能软件.在2020年 你可以从一台售价59美元的单板计算机中获得令人惊叹的性能 让我们用它来 ...

  6. 使用Python+Dlib构建人脸识别系统(在Nvidia Jetson Nano 2GB开发板上)

    Nvidia Jetson Nano 2GB开发板是一款新的单板机,售价59美元,运行带有GPU加速的人工智能软件. 在2020年,你可以从一台售价59美元的单板计算机中获得令人惊叹的性能,让我们用它 ...

  7. 【人工智能】人脸识别系统【实验报告与全部代码】(QDU)

    写在前面,防止有傻乎乎的同学直接全文复制出现问题. 说实话,实现的比较水,就是调用了 dlib 库的函数实现的人脸检测和人脸识别: 唯一的难点,也确实比较难,就是实现双线程控制,详见报告: ResNe ...

  8. linux的系统监视器图片_用Nvidia Jetson Nano 2GB和Python构建一个价值60美元的人脸识别系统...

    作者|Adam Geitgey 编译|Flin 来源|medium 新的Nvidia Jetson Nano 2GB开发板(今天宣布!)是一款单板机,售价59美元,运行带有GPU加速的人工智能软件. ...

  9. 开源真香 离线识别率高 Python 人脸识别系统

    以往的人脸识别主要是包括人脸图像采集.人脸识别预处理.身份确认.身份查找等技术和系统.现在人脸识别已经慢慢延伸到了ADAS中的驾驶员检测.行人跟踪.甚至到了动态物体的跟踪. 由此可以看出,人脸识别系统 ...

最新文章

  1. MMDrawerController(第三方类库)侧边栏的使用
  2. 【贪心】P1056 排座椅
  3. Tricks with Direct Memory Access in Java
  4. Hacking techniques automation
  5. CF1603C-Extreme Extension【整除分块,dp】
  6. [转]ubuntu network is unreachable 解决记
  7. CNN-RNN中文文本分类,基于TensorFlow 实现
  8. nbi可视化_用数据可视化的方式做汇报,更容易显现成绩、升职加薪更近一步
  9. spingCloud 整合netty
  10. python算法-冒泡排序
  11. 稀疏表示(Sparse Representations)
  12. 防止 跨站请求伪造(CSRF)
  13. 以大学生活为主题html,大学生活散文800字范文-以校园生活为话题的抒情散文800字?...
  14. 深入浅出JMS(二)——JMS的组成
  15. Tensorflow Keras模型和Estimator有什么区别?
  16. MIUI12 for OnePlus 7T 使用钱包app 的尝试
  17. 2010考研数学二第(15)题——导数应用:单调区间与极值
  18. linux中comm的用法,Linux之comm命令
  19. [siggraph2011]Secrets of CryENGINE 3 Graphics Technology
  20. c/c++ 表达式求值

热门文章

  1. 三句话归纳数据库三范式
  2. 全球及中国PTA(纯对苯二甲酸)市场竞争力及投资可行性分析报告2022~2028年
  3. Simple-fasterrcnn源码学习笔记(4)
  4. Unity中使用多个灯光时有的灯光没有效果的问题
  5. 基于TensorRT的语义分割实验记录
  6. 小技巧!微信发朋友圈长文字怎样才能避免被折叠成一行?
  7. QQ邮箱/163邮箱等怎么代收微软@hotmail/@outlook的邮件
  8. Android手机应用商城项目,Android手机助手项目实战:从0开发一款自己的应用商店...
  9. SSH 端口转发多级端口转发
  10. 我的世界服务器掉落率修改,[管理|综合]Scavenger —— 拾荒者,死亡不掉落[1.2.3-1.7.4]...