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('\n 请输入你的ID:')

    print('\n 数据初始化中,请直视摄像机录入数据....')

    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衍生的各种库产生了更多恐惧。好在队友之间能线上线下交流,一起攻克,解决了不少难题。
posted @ 2020-06-27 21:50  lyhbk  阅读(471)  评论(0编辑  收藏  举报