zoukankan      html  css  js  c++  java
  • 系统结构实践期末大作业

    选题简介

    我们本次的系统结构实践期末大作业是一个身份认证系统。该系统在人脸识别开源的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在图像处理方面的强大功能,这使得在进行图像处理的代码编写上简单了许多,放掉了想对图像像素点值处理的想法。还有在这里为黄恒杰组长辛苦劳作说一声谢谢,组长不仅分工安排合理,还十分的强大。

  • 相关阅读:
    LIS例题
    基数排序板子
    lower_bound和upper_bound在刷leetcode的时候...
    leetcode1081/316 求字典序最小的包含所有出现字符一次的子序列
    PHP 求多个数组的笛卡尔积,适用于求商品规格组合 【深度优先搜索】【原创】
    PHP 求多个数组的笛卡尔积,适用于求商品规格组合【原创】
    Spring 中注入 properties 中的值
    Java 枚举活用
    Intellij IDEA 快捷键整理(TonyCody)
    WIN API -- 2.Hello World
  • 原文地址:https://www.cnblogs.com/linguoqin/p/13198658.html
Copyright © 2011-2022 走看看