系统结构实践期末大作业

选题简介

我们本次的系统结构实践期末大作业是一个身份认证系统。该系统在人脸识别开源的python库face_recognition的基础上,进行修改示例代码,搭建lnmp框架,构建web项目,拉取MySQL容器等等工作来完成的。身份认证系统在识别人脸的过程中,会从数据库中得到所识别对象的信息,若无法识别,则会不进行显示;在对象信息的调整上,是通过web项目完成的,进行信息的增删改查。

设计

文件结构

lnmp框架

代码

首先进行对图片库加载和学习识别的半自动化

# 保存的图片文件名
image_name_list = []


# 得到文件名
def file_name(image_name_list):   
    # root是指当前目录路径(文件夹的绝对路径)
    # dirs是指路径下所有的子目录(文件夹里的文件夹)
    # files是指路径下所有的文件(文件夹里所有的文件)
    for root,dirs,files in os.walk(file_dir):
        for file in files:
            # if os.path.splitext(file)[1] == '.jpg':
                image_name_list.append(os.path.join(file))
                print(image_name_list)
                            
file_name(image_name_list)


# 创建已知面孔及其名称数组
known_face_encodings = []
known_face_names = []


# 加载图片并学习如何识别它
def konwn_face(known_face_encodings,known_face_names):
    for image_name in image_name_list :
        character_image = face_recognition.load_image_file(file_dir+image_name)
        character_face_encoding = face_recognition.face_encodings(character_image)[0]
        known_face_encodings.append(character_face_encoding)

    for root,dirs,files in os.walk(file_dir):
        for file in files:
                known_face_names.append(os.path.splitext(file)[0])
                                
konwn_face(known_face_encodings,known_face_names)

设定阈值

若阈值太低,容易造成无法成功识别人脸,结果如下:

反之,若阈值太高,就会人脸识别混淆,结果如下:

所以阈值太低容易造成无法成功识别人脸,太高容易造成人脸识别混淆,并且识别亚洲人所需要阈值tolerance一般要用低一点。

for face_encoding in face_encodings:
            # See if the face is a match for the known face(s)
            # 查看该面孔是否与已知面孔匹配
            matches = face_recognition.compare_faces(known_face_encodings, face_encoding,tolerance=0.5)
            
            # 默认为unknown
            name = "Unknown"

            # 使用与新面孔距离最小的已知面孔,即看测试图像与已知面孔之间有多远
            face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
            
            #best_match_index为face_distances中最小值的下标
            best_match_index = np.argmin(face_distances)
            
            #如果face_distances[best_match_index]小于0.5(截止值,原本想加上的,但仔细一想又好像不对),matches[best_match_index]比较结果为真
            if matches[best_match_index]:
                name = known_face_names[best_match_index]

            face_names.append(name)

未识别到人脸的信息

呈现在常态和未识别到时的信息面板内容。

    #text
    rectangular_image = cv2.imread(rectangular_dir)
    font = cv2.FONT_HERSHEY_DUPLEX
    cv2.putText(rectangular_image, "FACE PLEA!", (0 + 150, 0 + 330), font, 4, (255, 255, 255), 2)

已识别到人脸的信息

呈现已识别到时的信息面板内容。

            #mysql
            rectangular_image = cv2.imread(rectangular_dir)
            id=name
            sql = "SELECT * FROM User \
                   WHERE id = %s" % (id)
            results=mysql.mysql_find(cursor,sql)
            if(results!=None):
                for row in results:
                    lname = row[1]
                    age = row[2]
                    sex =row[3]
                    iden = row[4]
                    nation = row[5]

                # 画一个有名字的标签
                #cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
                font = cv2.FONT_HERSHEY_DUPLEX
                cv2.putText(rectangular_image, "NAME: "+lname, (0 + 50, 0 + 100), font, 2.0, (255, 255, 255), 2)
                cv2.putText(rectangular_image, "AGE: "+age, (0 + 50, 0 + 200), font, 2.0, (255, 255, 255), 2)
                cv2.putText(rectangular_image, "SEX: "+sex, (0 + 50, 0 + 300), font, 2.0, (255, 255, 255), 2)
                cv2.putText(rectangular_image, "IDENTITY: "+iden, (0 + 50, 0 + 400), font, 2.0, (255, 255, 255), 2)
                cv2.putText(rectangular_image, "NATION: "+nation, (0 + 50, 0 + 500), font, 2.0, (255, 255, 255), 2)

摄像头界面、信息面板、边框图片整合

首先来了解一下掩膜(mask)的概念:掩膜是用一副二值化图片对另外一幅图片进行局部的遮挡。

将边框图片用来作为掩膜,即灰度化处理

    # 边框图片
    bor_image = cv2.imread(border_dir)
    
    # 变更为画布的大小
    bor_image = cv2.resize(bor_image, (frame.shape[1], frame.shape[0]) )
    
    #roi
    rows,cols,channels = bor_image.shape
    roi = frame[0:rows, 0:cols ]
    
    # 利用mask合成
    # 将图片灰度化(灰度0-255  白255  黑0)
    bor_image_gray = cv2.cvtColor(bor_image,cv2.COLOR_BGR2GRAY)

将灰度图取反,其结果与原图分别作用于所需的两张素材,即相当于在原图中按位与运算边框图片的灰度图,使得在原图所对应的边框位置值为0;在边框图片按位与取反的灰度图,使得除边框外部分的值为0。

    # 灰度图 把 大于175(即不感兴趣)的值改为 255 ,也就是变为白色   
    # 现在是mask中 兴趣区域-->黑色   无兴趣区域-->白色
    ret, mask = cv2.threshold(bor_image_gray, 180, 255, cv2.THRESH_BINARY)
    
    # 把mask取反,现在是mask_not中 兴趣区域-->白色   无兴趣区域-->黑色
    mask_not = cv2.bitwise_not(mask)
    
    # 对图片和mask进行取与操作,作用相当于把mask中为黑色()的部分,
    # 在图片中也附黑,白色部分不变。
    img1_bg = cv2.bitwise_and(roi,roi,mask = mask)
    
    # 对边框图片和mask_not进行取与操作,作用相当于把mask中为黑色的部分,
    # 在边框图片中也附黑,白色部分不变。
    img2_bg = cv2.bitwise_and(bor_image,bor_image,mask = mask_not)

进行图片的加和

    # 进行图片的加和
    dst = cv2.add(img1_bg,img2_bg)
    frame[0:rows, 0:cols ] = dst
    
    
     #add the rectangular
    rectangular_image = cv2.resize(rectangular_image, (frame.shape[1], frame.shape[0]), )
    vtich = np.vstack((frame, rectangular_image))

mysql.py

import pymysql

def mysql_connect():
    connect = pymysql.connect(
        host='localhost',
        port=3306,
        user='root',
        passwd='123',
        db='myDB',
        charset='utf8'
    )
    if(connect!=None):
        print("connect mysql success!")
        return connect.cursor()
    
    
def mysql_find(cursor,sql):
    try:
        cursor.execute(sql)
        results = cursor.fetchall()
        for row in results:
            name = row[1]
            age = row[2]
            sex =row[3]
            iden = row[4]
            nation = row[5]
            print ("name=%s,age=%s,sex=%s,iden=%s,nation=%s" % \
                   (name, age, sex, iden, nation ))
            return results
    except:
        print ("Error: unable to fecth data")

web项目

MySQL容器

树莓派运行结果

组内分工 + 贡献比

学号 姓名 分工 贡献比
031702220 黄恒杰 框架搭建+实际操作+web前端 50%
031702223 郑志强 资料查询+php连接 20%
031702239 林国钦 身份识别代码+PPT、博客编写 30%

总结

⭐ 黄恒杰:本身在机缘巧合下拿到了树莓派,就产生了比较浓厚的兴趣,所以这次大作业我就直接基于树莓派的人脸识别来开展。我们组这次的大作业,可以说真的是三个菜鸟,基于所有已经学过的docker知识,还有平时一步步踏踏实实做好实验的经验,堆积起来了这个还算不小的项目。从python环境下跑人脸识别拓展到拉取mysql镜像容器来存取身份信息的身份识别,再到利用已经学过的lnmp集群框架来实现web服务,这一切似乎不简单但却可行性非常高。其中还拓展了图像功能来呈现身份识别的良好效果,可以说是比较创新的一点。在这里我也很感谢两个组员的配合,虽然实验中遇到了非常多的坎,虽然每个人的能力并没特别突出,但配合起来还是能产生很大的创作性的。即使因为时间有限,最后没有做的尽善尽美,但我们都还是很欣慰最后的那个项目的成果
⭐ 郑志强:从刚刚接触到系统综合实践这门课起,我就感受到这是一门实践性很强、理论性也很强的课程,所以每次作业时,我们组都进行了屏幕分享,视频等方式进行交流、沟通、探讨。
⭐ 林国钦:经过三周的实践操作,我们的作业已经完成。虽然过程中也遇到了很多问题,但通过查询资料,我们基本上都能够解决。本次实验我感受到了cv2在图像处理方面的强大功能,这使得在进行图像处理的代码编写上简单了许多,放掉了想对图像像素点值处理的想法。还有在这里为黄恒杰组长辛苦劳作说一声谢谢,组长不仅分工安排合理,还十分的强大。

posted @ 2020-06-28 01:01  Wasted  阅读(197)  评论(0编辑  收藏  举报