一、选题简介
本项目是将树莓派摄像头采集到的人脸根据数据库中已经存储的图片名和本地已有的图片进行识别,并将访问者的来访时间,姓名等信息录入数据库,如果是陌生人则会进行拍照并录入时间,适用于小区,公司,家庭等区域的监控。
二、设计
1,mysql容器的相关部署
-
拉取mysql镜像
-
根据docker文件建立属于自己的镜像
#基础镜像
FROM ibex/debian-mysql-server-5.7
#作者信息
MAINTAINER lzs<https://www.cnblogs.com/tinygod/>
#设置root密码
ENV MYSQL_ROOT_PASSWORD 123456
#设置不可免密登录
ENV MYSQL_ALLOW_EMPTY_PASSWORD no
-
运行容器
-
mysql容器的初始化在后文,经过多次尝试,最后使用的mysql容器不是图中的mysql而是mysqlsbb。
-
为主机的访问添加权限
docker inspect --format '{{ .NetworkSettings.IPAddress }}' mysqlsbb
//查询容器的ip地址,用以连接mysql
- 其次是为主机访问mysql添加权限,否则mysql会拒绝主机的访问
2,人脸识别微服务部署
-
安装opencv,拉取镜像,根据dockerfile建立属于自己的镜像,运行容器,在容器中安装人脸识别的相关模块。
具体在第七次实验,此处不再赘述。 -
在容器中安装用于数据库连接的MySQLdb并提交为一个新的镜像(原本使用pymysql,一根筋刚了十二小时以后换了MySQLdb)
pip3 install mysqlclient==1.3.10
提交镜像忘记截图了,此处给出部分信息:
-
运行容器,同时挂载本地目录的/home/pi/docker文件夹,为之后修改代码和识别到人脸进行拍照提供方便。
3,运行结果,展示容器启动后,程序的运行结果
- 部分代码展示
初始化数据库代码:建表,插入相关数据等。
# coding=utf-8
import MySQLdb
import time
import datetime
#创建mysql表
def createTable():
# 链接mysql数据库
db=MySQLdb.connect("172.17.0.3","root","123456")
# 创建指针
cursor = db.cursor()
# 创建authentication 数据库, 如果存在则删除authentication 数据库
#cursor.execute("drop database if exists authentication")
#cursor.execute("create database authentication")
#选择 authentication 这个数据库
cursor.execute("use authentication")
#sql中的内容为创建一个名为users的表
sql = """CREATE TABLE IF NOT EXISTS `users` (
`id` INT UNIQUE PRIMARY KEY ,
`name` VARCHAR (20)
)"""
#如果存在student这个表则删除
#cursor.execute("drop table if exists users")
#创建表
cursor.execute(sql)
print("successfully create table")
#sql中的内容为创建一个名为recorder的表
sql = """CREATE TABLE IF NOT EXISTS `recorder` (
`time` VARCHAR (30),
`name` VARCHAR (20)
)"""
#如果存在student这个表则删除
#cursor.execute("drop table if exists recorder")
#创建表
cursor.execute(sql)
# 提交到数据库执行
db.commit()
# 关闭游标链接
cursor.close()
# 关闭数据库服务器连接,释放内存
db.close()
print("successfully create table")
#在表users中插入数据
def insertUsers(id,name):
# 链接mysql数据库
db=MySQLdb.connect("172.17.0.3","root","123456")
# 创建指针
cursor = db.cursor()
#选择 authentication 这个数据库
cursor.execute("use authentication")
# 插入数据
sql = "INSERT IGNORE INTO users (id,name)VALUES("+str(id)+",'"+name+"');"
try:
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
print("successfully insert data")
except:
print("failed insert data")
#发生错误时回滚
db.rollback()
# 关闭游标链接
cursor.close()
# 关闭数据库服务器连接,释放内存
db.close()
if __name__ == '__main__':
createTable()
names=['Obama','Jackie Chan','MaYun','Jay Chou','Chester Bennington','shenteng','Mandela']
for i in range(7):
insertUsers(i,names[i])
- 操作代码和识别代码大致如下(部分)
# coding=utf-8
import face_recognition
import picamera
import numpy as np
import sqlop #数据库操作的各种方法
import time
import datetime
filedir = r"images/" #图片存放目录
# Get a reference to the Raspberry Pi camera.
# If this fails, make sure you have a camera connected to the RPi and that you
# enabled your camera in raspi-config and rebooted first.
camera = picamera.PiCamera()
camera.resolution = (320, 240)
output = np.empty((240, 320, 3), dtype=np.uint8)
known_face_encodings = []
known_face_names = []
# Load a sample picture and learn how to recognize it.
print("Loading known face image(s)")
result=sqlop.readUsers()#Users数据库全部结果
count=sqlop.countUsers()#Users数据库数据记录数
for i in range(0,count[0][0]): #根据读取结果录入已知图片
image = face_recognition.load_image_file(filedir+str(result[i][0])+".jpg")
face_encoding = face_recognition.face_encodings(image)[0]
known_face_encodings.append(face_encoding)#人脸代码数组的初始化
known_face_names.append(result[i][1])#名字数组的初始化
# coding=utf-8
import MySQLdb
import time
import datetime
#创建mysql表
def createTable():
# 链接mysql数据库
db=MySQLdb.connect(host="172.17.0.3",user="root",password="123456",database="authentication")
# 创建指针
cursor = db.cursor()
# 创建authentication 数据库, 如果存在则删除authentication 数据库
#cursor.execute("drop database if exists authentication")
#cursor.execute("create database authentication")
#选择 authentication 这个数据库
#cursor.execute("use authentication")
#sql中的内容为创建一个名为users的表
sql = """CREATE TABLE IF NOT EXISTS `users` (
`name` VARCHAR (20),
`img_src` VARCHAR (50)
)"""
#如果存在student这个表则删除
#cursor.execute("drop table if exists student")
#创建表
cursor.execute(sql)
-
运行python容器,执行init.py对mysql容器进行初始化
-
调用识别代码TEST.py进行识别
当人数发生变化时,代码会智能识别,并将其录入数据库。
-
当识别到陌生人出现时,代码会自动进行拍照并录入时间进行记录。
图中王宝强即为28号晚00.31分记录的陌生人。
4,组内分工和贡献比
分工占比 | 姓名 | 分工 |
---|---|---|
33.3% | 连振升 | 负责人脸识别部分的代码编写,代码的整合,整合代码的测试和排错。 |
33.3% | 童圣滔 | 负责树莓派操作和解决实际问题,整合代码的排错和修改。撰写博客。 |
33.3% | 范文辉 | 数据库部分的代码编写,整合代码的修改和排错,部分功能的添加和排错。 |
5,相关问题和解决办法:
- 数据库连接报2002,1698等错误。
- 1,抛弃Pymysql模块而用MySQLdb模块;2,给mysql容器授权本机ip的访问权限(本机ip有时会变,得重新授权);3,参数如果缺省必须按顺序规矩的写,否则要把对应的参数名列出来并严格对标格式。
- python容器里关于数据库连接的模块和关于识别的模块分别在pytho2.7和python3.5中。
- MySQLdb的安装方法与其他模块的有些不同,卸载掉python2以后,使用pip3 install mysqlclient==1.3.10即可。
- 监控到陌生人时无法边录像,提示已被占用
- 改为将陌生人拍下来的方式。
- 数据库连接经常提示int无法转化为str的错误
- 调试,在对应语句的int前加上str()
5,总结
- 连振升:本学期这门课让我了解到了微服务这一全新的领域,给我的大体感觉就是:微服务算是个小的虚拟机,我们可以在里面进行一些在主机里面被限制的操作。通过一个学期的实践和练习,我对docker有了一定的理解和运用熟练程度,虽不能真正利用docker进行大型项目的开发,但也是收益颇丰。还有就是认识到了树莓派这种微型计算机,真可谓麻雀虽小,五脏俱全,解析音频、视频、图片等文件都不在话下。但其系统结构还是与我们日常使用的主机有所区别,以后若有机会,我希望能够深入学习这方面的知识。
- 童圣滔:在本次的实验中我负责树莓派的实际操作,虽然我们的实验看着内容很少(确实也很少),但是我们三个确实花了无数的时间在里面,我从一开始对镜像和容器的概念都有些模糊,到现在靠着自己成功完成了一个大作业,从一开始通宵都解决不了一个小小的数据库容器连接的问题,到现在能在容器与容器间任意连接操作,虽然很苦,但也很快乐。两度转战虚拟机,两度拿起树莓派,身经千百问题,还是硬着头皮做了下来。这次实验不仅收获的是知识,更是意志和团结。
- 范文辉:感觉这门课程着重于微服务,熟悉容器镜像等等的搭建。学过这门课后,我对docker等一些微服务有了一定的了解。通过微服务,我们能够在树莓派这样的小机器中进行一些比较复杂的操作,完成特定的功能。本次实验,是前面实验的综合运用,将前面学到的知识熟练运用。实验中我们用到了mysql、人脸识别,python连接数据库等前面所学知识,遇到了一些困难,如连接数据库的时候频繁出错。经过我们的不懈努力,终于将它克服,实现了我们想要的功能。通过这次实验,我们得到了很好的成长。