当前位置:   article > 正文

人脸识别之数据库存取_人脸数据保存数据库接口

人脸数据保存数据库接口

一、程序概况

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

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

二、程序分析

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

2.利用face_recognition,可以很轻易地得到人脸128维的人脸编码,并且通过比对函数,就可以得出想要的结果。但是,128维的人脸编码是一个numpy ndarray类型,即矩阵,并不能存进数据库,要想存进数据库,必须进行类型转换,我的做法是先将矩阵转为列表,再将列表里的每个元素转为字符串,再用字符串拼接的方式拼成一个字符串,这时就可以把特征值存进数据库了。

3.既然是特征值的比对,那么从数据库取完数据之后,就需要把字符串重新转为矩阵格式,我的做法是先通过字符串切割,转为列表,再对列表里每个元素转为浮点型(float),最后再转为矩阵。

4.常规做法通过人脸识别后想要在图像上输出被识别者姓名,但是opencv有自己的一套编码规范,无法输出中文,如果保存的是中文,那么就会出现乱码的情况。出于强迫症,我就是要输出中文。我的做法是通过调用本地已存在的字体,利用PIL进行格式转换。

 三、环境搭建(基于Ubuntu系统):

1.如果没有安装pip3,请使用以下命令进行安装:

   安装pip3:sudo apt-get install python3-pip

   升级pip3:sudo pip3 install --upgrade pip

2.安装boost库:sudo apt-get install libboost-all-dev

3.安装cmake:sudo apt-get install cmake

4.安装dlib:sudo pip3 install dlib

5.安装opencv:sudo pip3 install opencv_python==3.4.2.16

6.安装PyMySQL:sudo pip3 install PyMySQL

7.安装face_recognition:sudo pip3 install face_recognition

备注:安装face_recognition过程中会自动安装numpy、scipy等

四、准备工作

对于MySQL数据库的操作采用Navicat可视化工具,数据库为test,表为face。

如图:

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

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

五、程序代码

1.feature.py #将人脸特征保存进数据库

  1. import face_recognition
  2. import pymysql
  3. # 加载图像及获取人脸特征
  4. def load_image(input_image, input_name):
  5. # 加载本地图像文件到一个numpy ndarray类型的对象上
  6. image = face_recognition.load_image_file(input_image)
  7. # 返回图像中每个面的128维人脸编码
  8. # 图像中可能存在多张人脸,取下标为0的人脸编码,表示识别出来的最清晰的人脸
  9. image_face_encoding = face_recognition.face_encodings(image)[0]
  10. # 将numpy array类型转化为列表
  11. encoding__array_list = image_face_encoding.tolist()
  12. # 将列表里的元素转化为字符串
  13. encoding_str_list = [str(i) for i in encoding__array_list]
  14. # 拼接列表里的字符串
  15. encoding_str = ','.join(encoding_str_list)
  16. # 被识别者姓名
  17. name = input_name
  18. # 将人脸特征编码存进数据库
  19. save_encoding(encoding_str, name)
  20. # 人脸特征信息保存
  21. def save_encoding(encoding_str, name):
  22. # 创建数据库连接对象
  23. conn = pymysql.connect(
  24. # 数据库的IP地址
  25. host="127.0.0.1",
  26. # 数据库用户名称
  27. user="root",
  28. # 数据库用户密码
  29. password="123456",
  30. # 数据库名称
  31. db="test",
  32. # 数据库端口名称
  33. port=3306,
  34. # 数据库的编码方式 注意是utf8
  35. charset="utf8"
  36. )
  37. # 使用 cursor() 方法创建一个游标对象 cursor
  38. cursor = conn.cursor()
  39. # SQL插入语句
  40. insert_sql = "insert into face(name,encoding) values(%s,%s)"
  41. try:
  42. # 执行sql语句
  43. cursor.execute(insert_sql, (name, encoding_str))
  44. # 提交到数据库执行
  45. conn.commit()
  46. except Exception as e:
  47. # 如果发生错误则回滚并打印错误信息
  48. conn.rollback()
  49. print(e)
  50. # 关闭游标
  51. cursor.close()
  52. # 关闭数据库连接
  53. conn.close()
  54. if __name__ == '__main__':
  55. load_image("yangchaoyue.jpg", "杨超越")
  56. load_image("zhangyishan.jpg", "张一山")

将以下两张图片中人物的人脸特征存入数据库

        

此时已经将人物的人脸特征存入到数据库中

2.recognition.py #人脸识别程序

  1. import face_recognition
  2. import cv2
  3. import pymysql
  4. import numpy as np
  5. from PIL import Image, ImageDraw, ImageFont
  6. # 人脸特征编码集合
  7. known_face_encodings = []
  8. # 人脸特征姓名集合
  9. known_face_names = []
  10. # 从数据库获取保存的人脸特征信息
  11. def get_info():
  12. # 创建数据库连接对象
  13. conn = pymysql.connect(
  14. # 数据库的IP地址
  15. host="127.0.0.1",
  16. # 数据库用户名称
  17. user="root",
  18. # 数据库用户密码
  19. password="123456",
  20. # 数据库名称
  21. db="test",
  22. # 数据库端口名称
  23. port=3306,
  24. # 数据库的编码方式 注意是utf8
  25. charset="utf8"
  26. )
  27. # 使用 cursor() 方法创建一个游标对象 cursor
  28. cursor = conn.cursor()
  29. # SQL查询语句
  30. sql = "select * from face"
  31. try:
  32. # 执行SQL语句
  33. cursor.execute(sql)
  34. # 获取所有记录列表
  35. results = cursor.fetchall()
  36. # 返回的结果集为元组
  37. for row in results:
  38. name = row[1]
  39. encoding = row[2]
  40. # print("name=%s,encoding=%s" % (name, encoding))
  41. # 将字符串转为numpy ndarray类型,即矩阵
  42. # 转换成一个list
  43. dlist = encoding.strip(' ').split(',')
  44. # 将list中str转换为float
  45. dfloat = list(map(float, dlist))
  46. arr = np.array(dfloat)
  47. # 将从数据库获取出来的信息追加到集合中
  48. known_face_encodings.append(arr)
  49. known_face_names.append(name)
  50. except Exception as e:
  51. print(e)
  52. # 关闭数据库连接
  53. conn.close()
  54. # 加载视频图像
  55. def load_image():
  56. # 打开摄像头 0代表笔记本的内置摄像头,1代表外置摄像头
  57. video_capture = cv2.VideoCapture(0)
  58. # 得到特征信息
  59. get_info()
  60. process_this_frame = True
  61. while True:
  62. # 读取摄像头画面
  63. ret, frame = video_capture.read()
  64. # 利用opencv的缩放函数改变摄像头图像的大小,图像越小,所做的计算就少
  65. small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
  66. # opencv的图像是BGR格式的,而我们需要是的RGB格式的,因此需要进行一个转换。
  67. rgb_small_frame = small_frame[:, :, ::-1]
  68. # 处理每一帧的图像
  69. if process_this_frame:
  70. # 使用默认的HOG模型查找图像中的所有人脸
  71. face_locations = face_recognition.face_locations(rgb_small_frame)
  72. # 如果硬件允许,可以使用GPU进行加速,此时应改为CNN模型
  73. # face_locations = face_recognition.face_locations(image, number_of_times_to_upsample=0, model="cnn")
  74. # 返回128维人脸编码,即人脸特征
  75. face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
  76. face_names = []
  77. # 将得到的人脸特征与数据库中的人脸特征集合进行比较,相同返回True,不同返回False
  78. for face_encoding in face_encodings:
  79. # matches:一个返回值为True或者False值的列表,该表指示了known_face_encodings列表的每个成员的匹配结果
  80. # tolerance:越小对比越严格,官方说法是0.6为典型的最佳值,也是默认值
  81. # 这里我设置0.45为最佳,可能跟我硬件有关
  82. matches = face_recognition.compare_faces(known_face_encodings, face_encoding, tolerance=0.45)
  83. # 默认为unknown
  84. name = "Unknow"
  85. if True in matches:
  86. first_match_index = matches.index(True)
  87. name = known_face_names[first_match_index]
  88. print('已存在')
  89. else:
  90. print('不存在')
  91. face_names.append(name)
  92. process_this_frame = not process_this_frame
  93. # 将捕捉到的人脸显示出来
  94. for (top, right, bottom, left), name in zip(face_locations, face_names):
  95. # 恢复显示的图像大小
  96. top *= 4
  97. right *= 4
  98. bottom *= 4
  99. left *= 4
  100. # CV库有自己的编码规范,要想在图像上输出中文,需将图片格式转化为PIL库的格式,用PIL的方法写入中文,然后在转化为CV的格式
  101. # cv2和PIL中颜色的hex码的储存顺序不同
  102. cv2img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
  103. pilimg = Image.fromarray(cv2img)
  104. # PIL图片上打印汉字
  105. draw = ImageDraw.Draw(pilimg)
  106. # NotoSansCJK-Light.ttc为本机上已有的字体,可通过locate *.ttc进行查询
  107. font = ImageFont.truetype("NotoSansCJK-Light.ttc", 30, encoding="utf-8") # 参数1:字体文件路径,参数2:字体大小
  108. draw.text((left + 10, top - 40), name, (255, 255, 255), font=font) # 参数1:打印坐标,参数2:文本,参数3:字体颜色,参数4:字体
  109. # PIL图片转cv2 图片
  110. frame = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
  111. # 对人脸画出矩形框
  112. cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
  113. # 如果只想输出英文,可以省略以上步骤,编写以下代码即可
  114. # 显示的字体类型
  115. # font = cv2.FONT_HERSHEY_TRIPLEX
  116. # 打印识别信息
  117. # cv2.putText(frame, name, (left + 6, top - 6), font, 1.0, (255, 255, 255), 1)
  118. # 显示图像
  119. cv2.imshow('monitor', frame)
  120. # 按Q退出
  121. if cv2.waitKey(1) & 0xFF == ord('q'):
  122. break
  123. # 释放摄像头资源
  124. video_capture.release()
  125. # 关闭显示图像的窗口
  126. cv2.destroyAllWindows()
  127. if __name__ == '__main__':
  128. load_image()

输出结果(演示结果是导进去两张静态图片出来的结果):

备注:将自己的图片进行导入,便可以看到实际效果

                             

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/606558
推荐阅读
相关标签
  

闽ICP备14008679号