• 2020系统综合实践 期末大作业 04组


    目录

    (1)选题简介

    • 新冠肺炎疫情蔓延,各地防控措施严格,众多应届毕业生无法返回学校,大学生生涯重要纪念——毕业照面临无法拍摄的窘境,由此许多高校毕业生自发用P图的方式,打造自己班级的毕业照。我们小组希望借助这次大作业的契机,结合微服务打造一个简单实用的云毕业照。

    (2)设计部署

    设计

    1.基于LBPH原理的人脸识别

    • LBPH(Local Binary PatternsHistograms)局部二进制编码直方图,建立在LBPH基础之上的人脸识别法基本思想如下:首先以每个像素为中心,判断与周围像素灰度值大小关系,对其进行二进制编码,从而获得整幅图像的LBP编码图像;再将LBP图像分为个区域,获取每个区域的LBP编码直方图,继而得到整幅图像的LBP编码直方图,通过比较不同人脸图像LBP编码直方图达到人脸识别的目的,其优点是不会受到光照、缩放、旋转和平移的影响。

    2.部分代码

    人脸收集

    def data_collection():
        cap = cv2.VideoCapture(0)
        # cv2.CAP_DSHOW是作为open调用的一部分传递标志,还有许多其它的参数,而这个CAP_DSHOW是微软特有的。
        face_id = input('
     请输入你的ID:')
    
        print('
     数据初始化中,请直视摄像机录入数据....')
    
        count = 0
    
        while True:
    
            # 从摄像头读取图片
    
            sucess, img = cap.read()
    
            # 转为灰度图片
    
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
            # 检测人脸
    
            faces = face_detector.detectMultiScale(gray, 1.3, 5)
    
            for (x, y, w, h) in faces:
                cv2.rectangle(img, (x, y), (x + w, y + w), (255, 0, 0))
                count += 1
                # 保存图像
                cv2.imwrite("facedata/Member." + str(face_id) + '.' + str(count) + '.jpg', gray[y: y + h, x: x + w])
                cv2.imshow('data collection', img)
    
            # 保持画面的持续。
    
            k = cv2.waitKey(1)
            if k == 27:  # 通过esc键退出摄像
                break
            elif count >= 200:  # 得到n个样本后退出摄像
                break
        cap.release()
        cv2.destroyAllWindows()
    

    人脸训练

    def face_training():
        # 人脸数据路径
        path = './facedata'
    
        recognizer = cv2.face.LBPHFaceRecognizer_create()
    
        def getImagesAndLabels(path):
            imagePaths = [os.path.join(path, f) for f in os.listdir(path)]  # join函数将多个路径组合后返回
            faceSamples = []
            ids = []
            for imagePath in imagePaths:
                PIL_img = Image.open(imagePath).convert('L')  # convert it to grayscale
                img_numpy = np.array(PIL_img, 'uint8')
                id = int(os.path.split(imagePath)[-1].split(".")[1])
                faces = face_detector.detectMultiScale(img_numpy)
                for (x, y, w, h) in faces:
                    faceSamples.append(img_numpy[y:y + h, x: x + w])
                    ids.append(id)
            return faceSamples, ids
    
        print('数据训练中')
        faces, ids = getImagesAndLabels(path)
        recognizer.train(faces, np.array(ids))
    
        recognizer.write(r'./trainer.yml')
    
    

    人脸识别

    def face_ientification(sourcePath, targetPath,  suffix):
        ImagePaths = getAllPath(sourcePath, suffix)
    
        count = 1
        recognizer = cv2.face.LBPHFaceRecognizer_create()
        recognizer.read('./trainer.yml')
        faceCascade = cv2.CascadeClassifier(Path)
    
        global namess
    
    
        for imagePath in ImagePaths:
            img = cv2.imread(imagePath)
            # 图像灰度处理
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
            # 将人脸用vector保存各个人脸的坐标、大小(用矩形表示)
            faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
    
            for (x, y, w, h) in faces:
                X = int(x * 1.0)
                W = min(int((x + w) * 1.0), img.shape[1])
                Y = int(y * 1.0)
                H = min(int((y + h) * 1.0), img.shape[0])
    
                f = cv2.resize(img[Y:H, X:W], (128, 128))
                idnum, confidence = recognizer.predict(gray[y:y + h, x:x + w])
    
                if confidence < 80:
                    namess = names[idnum]
                    confidence = "{0}%".format(round(100 - confidence))
    
                    cv2.imwrite(targetPath + os.sep + '%s' % namess + '%s' % confidence + '%s.jpg' % count, f)
                    count += 1
                    print(imagePath )
    

    人脸拼接

        def mark_pictures(self, SideLength, SideWide, type1):
            heart_image = Image.new('RGB', (128 * SideLength, 128 * SideWide))
            row = col = 0
            for side in range(SideLength * SideWide):
                if images_side_calc(col, row, type1):
                    img = Image.open(self.image_list.pop())
                    img = img.resize((128, 128), Image.ANTIALIAS)
                else:
                    img = Image.new("RGB", (128, 128), (0, 0, 0))
                heart_image.paste(img, (row * 128, col * 128))
                col += 1
                if col == SideWide:
                    col = 0
                    row += 1
                if row == SideLength and col == SideWide:
                    break
            heart_image.save("heart_image.jpg")
            img = cv2.imread("heart_image.jpg")
            cv2.namedWindow("Image", cv2.WINDOW_FREERATIO)
            cv2.imshow("Image", img)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
    

    部署

    1.建立挂载目录



    2.拉取镜像

    docker pull adnrv/opencv:latest
    


    pip list   #查看该容器的库
    

    • 代码用到的库cv2,os,csv,random,PIL,numpy。

    3.开权限并运行

    xhost +
    
    docker run -it --privileged --rm --device=/dev/video0 -e DISPLAY=unix$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/lyh/face:/face adnrv/opencv bash
    
    

    4.安装pillow库

    pip3 install pillow
    

    5.运行代码

    (3)运行结果

    运行界面

    人脸录入

    合照

    FZU拼图

    2020拼图

    心形拼图

    箭头拼图

    (4)小组协作

    学号 姓名 分工 贡献比
    031702234 林银河 人脸匹配识别,微服务部署 37%
    031702241 苏杰隆 人脸截取,微服务部署 33%
    031702236 王耀鑫 人脸拼接,微服务部署 30%

    (5)总结

    王耀鑫

    • 这次大作业,我们组尝试过树莓派的各种库安装,这个属实恶心,装完某个库,接着导入会跟你说该库缺少某个包,补上这个包后又来一个,感觉像在填无底天坑,最后我们小组放弃树莓派,直接部署到虚拟机上。通过这次学习,我尝试了许多可能,加深了对树莓派,docker的理解,也粗粗涉猎了点人脸识别,增长了见识,深感自身能力薄弱,还需继续努力。

    林银河

    • 通过这次大作业,我对于opencv的使用有了一个更加深入的了解,简单了解了如何使用opencv进行人脸识别。我们遇到的最大的困难就是微服务的部署,原本我们小组准备采用树莓派实现,但是适合树莓派的armv7镜像是在是太少了,我们也尝试过自己搞一个符合要求的镜像,但是失败了,总是提示缺失文件,补了一个还有其他文件,最终我们放弃使用树莓派,转向了虚拟机,通过这次这使我对docker容器的部署有了更加深入的体会。我对于团队协作的重要意义也有了更深的理解。

    苏杰隆

    • 这次的大作业,本来是想在树莓派上运行代码的,用树莓派自带的摄像头实现人脸数据录入,而且在中期汇报时,代码部分已基本完成,本以为只要接下来在树莓派完成部署就可以说是大功告成,没想到部署过程一路坎坷。适合树莓派的armv7的镜像实在太少,想自行配一个镜像,从pypi找的轮子又屡屡出错,查阅官方文档方才得知另有专属树莓派的piwheel。从下完轮子之后先是contrib版本过高无法兼容,下载了正确版本后又在安装过程中缺失文件,缺失文件一个接一个,踩坑无数,此处省略百来篇我们所搜索的解决方案。。。最后不得不转战虚拟机,在虚拟机上实现项目。经历了树莓派的折磨,在虚拟机上已轻车熟路,感觉自己对docker的理解又上升了一个档次。但是由于大量时间花费在部署上,自己对代码并没有进行认真的研究,因此感觉对opencv的学习不够透彻,只有对opencv衍生的各种库产生了更多恐惧。好在队友之间能线上线下交流,一起攻克,解决了不少难题。
  • 相关阅读:
    C#作为服务器端 MATLAB作为客户端 二者之间进行通信
    解决Socket通信中,经常遇到的问题——数据粘包的两种方法
    将之前的通信代码,以winform界面的形式写出来
    winform窗体程序之picturebox控件
    Socket通信
    Redis 高级教程 Redis 分区(6)
    Redis 高级教程 Redis 管道传输(5)
    Redis 高级教程 Redis 客户端连接(4)
    Redis 高级教程 Redis 基准(3)
    Redis 高级教程 Redis 安全(2)
  • 原文地址:https://www.cnblogs.com/lyhtsl/p/13200082.html
Copyright © 2020-2023  润新知