人脸识别——MySQL数据库存储人脸特征信息解决方案

需求描述

1.将人脸特征信息保存进MySQL数据库。

2.调用摄像头识别人脸,将待识别的人物进行识别,并实时地与数据库中的人脸特征信息进行比对,同时判断出被识别者的身份。

需求分析

1、准备

利用opencv、face_recognition、numpy、pymysql等Python第三方类库,官方说法是face_recognition的人脸识别准确率高达99.6%。

2、识别

利用face_recognition,可以很轻易地得到人脸128维的人脸编码,并且通过比对函数,就可以得出想要的结果。

3、编码

由于face_recognition的128维的人脸编码是一个numpy ndarray类型,即矩阵,并不能存进数据库,要想存进数据库,必须进行类型转换

思路:先将矩阵转为列表,再将列表里的每个元素转为字符串,再用字符串拼接的方式拼成一个字符串,这时就可以把特征值存进数据库了。

4.译码

既然是特征值的比对,那么从数据库取完数据之后,就需要把字符串重新转为矩阵格式。

思路:先通过字符串切割,转为列表,再对列表里每个元素转为浮点型(float),最后再转为矩阵。

5.输出

常规做法通过人脸识别后想要在图像上输出被识别者姓名,但是opencv有自己的一套编码规范,无法输出中文,如果保存的是中文,那么就会出现乱码的情况。

中文文字图像显示解决思路:通过调用本地已存在的字体,利用PIL进行格式转换。


解决方案

数据库设计 

FaceSQL.py:MySQL数据库处理相关

import pymysql

class FaceSQL:
    def __init__(self):
        self.conn = pymysql.connect(
            # 数据库的IP地址
            host="xxx.xxx.xxx.xxx",
            # 数据库用户名称
            user="******",
            # 数据库用户密码
            password="******",
            # 数据库名称
            db="xxx",
            # 数据库端口名称
            port=3306,
            # 数据库的编码方式 注意是utf8
            charset="utf8"
        )

    def processFaceData(self, sqlstr, args=()):
        print(sqlstr)
        # 使用 cursor() 方法创建一个游标对象 cursor
        cursor = self.conn.cursor()
        try:
            # 执行sql语句
            cursor.execute(sqlstr, args)
            # 提交到数据库执行
            self.conn.commit()
        except Exception as e:
            # 如果发生错误则回滚并打印错误信息
            self.conn.rollback()
            print(e)
        finally:
            # 关闭游标
            cursor.close()

    def saveFaceData(self,id,encoding_str):
        self.processFaceData("insert into face(学号,encoding) values(%s,%s)", (id, encoding_str))

    def updateFaceData(self, id, encoding_str):
        self.processFaceData("update face set encoding = %s where 学号 = %s", (encoding_str, id))

    def execute_float_sqlstr(self, sqlstr):
        # 使用 cursor() 方法创建一个游标对象 cursor
        cursor = self.conn.cursor()
        # SQL插入语句

        results = []
        try:
            # 执行sql语句
            cursor.execute(sqlstr)
            # 获取所有记录列表
            results = cursor.fetchall()
        except Exception as e:
            # 如果发生错误则回滚并打印错误信息
            self.conn.rollback()
            print(e)
        finally:
            # 关闭游标
            cursor.close()
        return results

    def sreachFaceData(self, id):
        return self.execute_float_sqlstr( "select * from face where 学号="+id)

    def allFaceData(self):
        return self.execute_float_sqlstr( "select * from face ")

    def sreach_Info(self,id):
        return self.execute_float_sqlstr( "select * from zstustu where 学号='" + id + "'")

FaceTools.py: 人脸特征信息处理相关

import face_recognition
import numpy
from os import listdir,path
from FaceSQL import FaceSQL
class FaceTools:
    def __init__(self):
        try:
            self.facesql=FaceSQL()
        except :
            print("数据库连接错误")

    def encoding_FaceStr(self, image_face_encoding):
        # 将numpy array类型转化为列表
        encoding__array_list = image_face_encoding.tolist()
        # 将列表里的元素转化为字符串
        encoding_str_list = [str(i) for i in encoding__array_list]
        # 拼接列表里的字符串
        encoding_str = ','.join(encoding_str_list)
        return encoding_str

    def decoding_FaceStr(self, encoding_str):
        # print("name=%s,encoding=%s" % (name, encoding))
        # 将字符串转为numpy ndarray类型,即矩阵
        # 转换成一个list
        dlist = encoding_str.strip(' ').split(',')
        # 将list中str转换为float
        dfloat = list(map(float, dlist))
        face_encoding = numpy.array(dfloat)
        return face_encoding

    def add_Face(self,image_name, id):
        # 加载本地图像文件到一个numpy ndarray类型的对象上
        image = face_recognition.load_image_file("./photo/"+image_name)
        # 返回图像中每个面的128维人脸编码
        # 图像中可能存在多张人脸,取下标为0的人脸编码,表示识别出来的最清晰的人脸
        image_face_encoding = face_recognition.face_encodings(image)[0]
        encoding_str =self.encoding_FaceStr(image_face_encoding)
        # 将人脸特征编码存进数据库
        self.facesql.saveFaceData(id,encoding_str)

    def updata_Face(self, image_name, id):
        # 加载本地图像文件到一个numpy ndarray类型的对象上
        image = face_recognition.load_image_file("./photo/"+image_name)
        # 返回图像中每个面的128维人脸编码
        # 图像中可能存在多张人脸,取下标为0的人脸编码,表示识别出来的最清晰的人脸
        image_face_encoding = face_recognition.face_encodings(image)[0]
        encoding_str = self.encoding_FaceStr(image_face_encoding)
        # 将人脸特征编码更新数据库
        self.facesql.updateFaceData(id, encoding_str)

    def sreach_Face(self, id):
        face_encoding_strs = self.facesql.sreachFaceData(id)
        # 人脸特征编码集合
        face_encodings = []
        # 人脸特征姓名集合
        face_names = []
        for row in face_encoding_strs:
            name = row[0]
            face_encoding_str = row[1]
            # 将从数据库获取出来的信息追加到集合中
            face_encodings.append(self.decoding_FaceStr(face_encoding_str))
            face_names.append(name)
        return face_names,face_encodings

    def load_faceoffile(self):
        filepath = 'photo'
        filename_list = listdir(filepath)
        # 人脸特征编码集合
        face_encodings = []
        # 人脸特征姓名集合
        face_names = []
        a = 0
        for filename in filename_list:  # 依次读入列表中的内容
            a += 1
            if filename.endswith('jpg'):  # 后缀名'jpg'匹对
                face_names.append(filename[:-4])  # 把文件名字的后四位.jpg去掉获取人名
                file_str = 'photo' + '/' + filename
                a_images = face_recognition.load_image_file(file_str)
                print(file_str)
                a_face_encoding = face_recognition.face_encodings(a_images)[0]
                face_encodings.append(a_face_encoding)
        print(face_names, a)
        return face_names,face_encodings
    def load_faceofdatabase(self):
        try:
            face_encoding_strs = self.facesql.allFaceData()
        except:
            print("数据库连接错误")
        # 人脸特征编码集合
        face_encodings = []
        # 人脸特征姓名集合
        face_names = []
        for row in face_encoding_strs:
            name = row[0]
            face_encoding_str = row[1]
            # 将从数据库获取出来的信息追加到集合中
            face_encodings.append(self.decoding_FaceStr(face_encoding_str))
            face_names.append(name)
        return  face_names, face_encodings
    def load_images_face(self,filepath):
        filename_list = listdir(filepath)
        for filename in filename_list:  # 依次读入列表中的内容
            if path.isdir(filepath+filename):
                self.load_images_face(filepath+filename+"\\")
            if filename.endswith('jpg'):  # 后缀名'jpg'匹对
                file_str = filepath + filename
                a_images = face_recognition.load_image_file(file_str)
                print(file_str)
                face_encoding = face_recognition.face_encodings(a_images)
                if face_encoding != []:
                    a_face_encoding = face_encoding[0]
                    encoding_str = self.encoding_FaceStr(a_face_encoding)
                    self.facesql.saveFaceData(filename[:-4], encoding_str)
    def load_images_faces(self, filepath):
        filename_list = listdir(filepath)
        a=0
        for filename in filename_list:  # 依次读入列表中的内容
            if filename.endswith('jpg'):  # 后缀名'jpg'匹对
                file_str = filepath + filename
                a_images = face_recognition.load_image_file(file_str)
                print(file_str)
                face_encoding = face_recognition.face_encodings(a_images)
                for a_face_encoding in face_encoding:
                    a += 1
                    encoding_str = self.encoding_FaceStr(a_face_encoding)
                    self.facesql.saveFaceData(filename[:-4] + "-" + str(a), encoding_str)



运行结果

教程资源

Navicat安装教程:https://blog.csdn.net/superit401/article/details/78110079/

Navicat中文乱码解决方案教程:https://blog.csdn.net/sinat_26546385/article/details/80381282

Python连接MySQL数据库:https://shentuzhigang.blog.csdn.net/article/details/103784064

face_recognition库安装教程:https://blog.csdn.net/weixin_40450867/article/details/81734815

[Anaconda+Jupyter Notebook+Python3.6]环境下安装face_recognition教程:https://shentuzhigang.blog.csdn.net/article/details/103746567

GitHub资源

face_recognition库官方GitHub:https://github.com/ageitgey/face_recognition/

简单人脸识别系统DEMO:https://github.com/niehen6174/image-and-speech-processing

参考文章

https://face-recognition.readthedocs.io/en/latest/readme.html

https://blog.csdn.net/qq_42109746/article/details/87281583

https://blog.csdn.net/Nirvana_6174/article/details/88362425

https://www.zhihu.com/tardis/sogou/art/25880933

### 嵌入式系统中的智能考勤项目设计 构建一个基于嵌入式的智能考勤系统是一个复杂的多学科任务,它涉及到硬件选型、软件开发以及数据库管理等多个方面。以下是关于如何实现该系统的详细说明。 #### 1. **嵌入式系统的选择** 对于嵌入式平台的选择,通常会考虑性能需求和成本之间的平衡。常见的选择包括树莓派 (Raspberry Pi),Jetson Nano 或者其他 ARM 架构的单板计算机 (SBC)[^2]。这些设备能够运行 Linux 操作系统并支持 OpenCV 和 MySQL 的安装与配置。 #### 2. **OpenCV 面部识别模块** OpenCV 是一种强大的开源图像处理,在面部检测和识别领域有着广泛的应用。可以采用 Haar 特征级联分类器或者更先进的深度学习模型如 Dlib 中的人脸特征提取方法来进行人脸验证工作流的设计[^3]: ```python import cv2 # 加载预训练好的Haarcascade XML文件路径 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') def detect_faces(image_path): img = cv2.imread(image_path) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30)) for (x,y,w,h) in faces: cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) return img ``` 上述代码片段展示了基本的脸部探测功能;实际应用中还需要进一步优化算法精度,并集成到整个考勤流程里去[^4]。 #### 3. **MySQL 数据库存储方案** 为了保存员工信息及其打卡记录,建议创建两个表结构——`employees` 表用来存储个人信息(ID号、姓名等),而 `attendance_records` 则负责记录每次签到的时间戳及其他关联字段。SQL 创建语句如下所示: ```sql CREATE TABLE employees ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), photo BLOB -- 可选项:如果需要存照片的话 ); CREATE TABLE attendance_records ( record_id INT AUTO_INCREMENT PRIMARY KEY, employee_id INT NOT NULL, check_in_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY(employee_id) REFERENCES employees(id) ); ``` 通过这样的方式就可以轻松查询某段时间内的具体出席情况了[^5]。 #### 4. **整体架构概述** 最后一步就是把这些组件结合起来形成完整的解决方案。这可能意味着编写脚本来定期捕获摄像头画面并通过调用前面提到过的函数完成身份确认操作后再更新至相应的数据库条目之中。此外还需注意安全性考量比如加密传输敏感资料等等[^6]。 ---
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Starzkg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值