基于虹软人脸识别,实现超市人脸支付
2021-08-05 14:12 码仔很忙 阅读(540) 评论(0) 编辑 收藏 举报前言
随着计算机和网络技术的不断发达,人脸识别在我们的生活中也不断的被应用,而无人超市以及在超市中的人脸支付并没有普及,本文作为一个项目进行超市人脸支付的场景测试与探索。
实现功能
使用python语言编写整个系统
PyQt5实现界面的搭建
虹软人脸识别sdk3.0实现人脸识别。
以下文章中代码均为示例代码 便于理解但不完整。完整项目在文章最后链接
1. 能够管理员登录,实现对顾客信息以及金额的增删查改功能的管理。
管理员登录需要输入正确的用户名以及密码。这部分通过配置文件来实现,将用户名及密码保存在conf文件中,通过configparser
库对conf文件进行读取的操作。
通过界面获取到用户的输入再与配置文件中信息进行比对,进行判断。
# 示例从conf文件中读取信息
from configparser import ConfigParser
conf=ConfigParser() #
conf.read('config.conf', encoding='gbk')#读取配置文件 获取一些参数
register_admin = conf.get('secret', 'admin')
register_value = conf.get('secret', 'value')
进入到管理员登录的界面后,即可对用户信息进行管理,可以支持增删查改的操作。
为了减少界面控空间,更改查找删除功能集成到一块,输入信息查找即可得出相关信息,对相关信息更改点击确定即可。对更改更多信息输入删除即可删除改用户的信息。
该部分也是对conf文件的操作,所有的用户信息在本地有信息记录(服务器也有同步信息)这部分也是对conf文件的写与读。以及从界面获取到输入。
# 示例 查找功能
self.lineEdit_17.setPlaceholderText(self.conf.get(search_name,'余额'))
self.lineEdit_18.setPlaceholderText(self.conf.get(search_name,'性别'))
self.lineEdit_20.setPlaceholderText(self.conf.get(search_name,'更多信息'))
conf文件中信息保存格式
2.能够通过人脸识别在界面上实时显示所剩金额。
界面使用pyqt5进行搭建,使用qtdesigner进行最初始的空间构建,这也是最简单的一种构建界面的方式。并对构建的界面进行美化
美化的部分可以参考我之前的一篇文章链接
。
人脸识别使用虹软人脸识别sdk3.0,并编译成python调用。具体调用和使用方式可以参考另一篇文章链接。
虹软的人脸识别sdk支持离线的人脸识别,速度快、精读高,满足我们这个场景的需要。
并且能够免费激活。
在本文本项目的使用中,也加入了一些优化,一些小算法,用于更快的提升人脸识别的速度。
(人脸识别流程图)
第一种方法是在人脸特征比对过程中缩短时间。在人脸识别过程中对检测到的人脸需要提取人脸特征,紧接着对提取的特征遍历人脸数据库。这样当人脸数据库非常大的时候,遍历就会非常的耗费时间,使得人脸识别的效率很低。这时设置一个阈值0.90,当匹配到人脸数据库中与该人的特征相似度达到0.90时,就认定是该人,中断遍历就不再进行接下来的人脸特征对比计算,这样就能够大大减小比对的时间。
第二种方法是针对不同的摄像头画面设计的。不同场景下使用的摄像头不同,摄像头的参数也会不同,最重要的是获取到的摄像头画面像素差别会很大,而每帧画面都需要传到人脸识别算法中去提取人脸特征进行人脸检测,画面越大就会导致速度越慢,另一方面对人脸提取特征不需要很高的像素图像而日常使用摄像头像素都会超高。在传入算法提取特征之前,对摄像头画面尺寸进行获取、判断、缩小,将缩小后的画面送入算法进行特征提取。
第三种方法是进行人脸跟踪从而减少人脸比对的次数,缩短人脸识别的时间。先进行人脸检测得出人脸坐标,进而进行使用IOU的计算进行人脸跟踪,并标注一个一直增加的ID编号。当下一帧图像检测出来跟上一帧是同一个人,这时就不需要再次进行人脸特征提取和比对,能够大大缩短人脸识别的时间。
3. 通过输入框输入支付金额,通过人脸识别实时进行支付对应的金额。
在输入框中输入需要支付的金额,即可对识别出的人脸对应的金额进行扣费,如果金额不足以支付,则进行弹窗提醒
如果用户的金额足以支付输入的金额,则能够进行扣费,并在界面上进行实时的显示出来所剩的金额。这部分其实并不复杂,将用户与金额进行绑定,然后对输入的金额数值进行获取,并对用户的所剩金额进行判断,执行对应的操作。
4.数据保存更新在本地与云数据库中。
用户图片只需要放入到项目目录下面的photo文件夹下,并使用名字进行命名
在用户信息的地方,使用用户名作为主键。
这是本地的数据,在代码中数据更新时,首先更新的是本地的数据,随后会更新云数据库中的数据。
云数据库中的信息保存,(截图不是同一时间下的,所以信息会有所不同)
使用pymysql
库对数据库进行一个连接,增删查改的操作。
示例 查询信息的函数
def querydb(db): # 查询所有信息
# 使用cursor()方法获取操作游标
cursor = db.cursor()
sql = "SELECT * FROM FaceInfor"
try:
# 执行SQL语句
cursor.execute(sql)
# 获取所有记录列表
results = cursor.fetchall()
print(results)
for row in results:
id = row[0]
name = row[1]
gender= row[2]
money = row[3]
# 打印结果
print ( "id: %s,姓名: %s,性别: %s, 余额: %s" % \
(id,name, gender, money))
return results
except:
print ( "Error: unable to fecth data")
return None
5.语音提示
当支付成功,与支付失败时需要使用语音进行提示。\
这里使用wave
pyaudio
库实现语音的播报\
下面代码为打开音频文件并播放
def play():
chunk = 1024 # 2014kb
wf = wave.open(r"8167.mp3", 'rb')
p = PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), channels=wf.getnchannels(),rate=wf.getframerate(), output=True)
nchannels, sampwidth, framerate, nframes = (wf.getparams())[:4]
data = wf.readframes(chunk) # 读取数据
t = time()
times = int(nframes / framerate)
while True:
data = wf.readframes(chunk)
stream.write(data)
if time() - t >= times:
print(data)
break
stream.stop_stream() # 停止数据流
stream.close()
p.terminate() # 关闭 PyAudio
print('play函数结束!')
另一方面,当语音播报的时候,主界面也需要同时进行,这时候就涉及到多线程的问题。在代码中当触发语音播报的条件时,需要开启一个线程用于播报,这样不会导致主界面人脸识别线程的卡顿。
这部分使用from PyQt5.QtCore import QThread
进行多线程的操作
signal_play = pyqtSignal()
def __init__(self):
super().__init__()
def run(self):
pass
else
目前还存在的问题
1. 与实际场景的超市支付还有差别,没有将商品信息进行链接。
1. 信息管理还略显简单
如果文章有帮助到你,关注 点赞 收藏!\
项目链接
了解更多人脸识别产品相关内容请到虹软视觉开放平台哦