zoukankan      html  css  js  c++  java
  • 2020系统综合实践 第7次实践作业 5组

    综合系统实践 第7次实践作业

    (1)在树莓派中安装opencv库

    在Raspberry Pi 4B上安装OpenCV 4.1.2

    安装OpenCV的进程可能非常耗时且需要安装许多依赖项和先决条件。

    ①展开文件系统

    如果使用全新的Raspbian Stretch安装,首先需要扩展文件系统,以包括micro-SD卡上的所有可用空间:

    sudo raspi-config
    

    然后选择“高级选项”菜单项

    接下来选择“扩展文件系统”

    回车确定

    选择finish

    然后重新启动Pi

    sudo reboot 
    

    重新启动后,文件系统应该已经扩展到包含micro-SD卡上的所有可用空间。可以验证该盘已被执行扩展和检查的输出

    df -h
    

    Raspbian文件系统已经扩展到包含所有16GB的micro-SD卡。

    但是,即使扩展了我的文件系统,我也已经使用了16GB卡的43%。

    一件简单的事情就是删除LibreOffice和Wolfram引擎,以释放Pi上的一些空间:

    sudo apt-get purge wolfram-engine
    sudo apt-get purge libreoffice*
    sudo apt-get clean
    sudo apt-get autoremove
    

    删除Wolfram引擎和LibreOffice后,可以回收近1GB!

    ②安装依赖关系

    # 更新和升级任何现有的软件包
    sudo apt-get update && sudo apt-get upgrade 
    # 安装开发工具CMake,帮助我们配置OpenCV构建过程
    sudo apt-get install build-essential cmake pkg-config
    # 图像I/O包,允许我们从磁盘加载各种图像文件格式。这种文件格式的例子包括JPEG,PNG,TIFF等
    sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
    # 视频I/O包。这些库允许我们从磁盘读取各种视频文件格式,并直接处理视频流
    sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
    sudo apt-get install libxvidcore-dev libx264-dev
    # OpenCV库附带一个名为highgui的子模块 ,用于在我们的屏幕上显示图像并构建基本的GUI。为了编译 highgui模块,我们需要安装GTK开发库
    sudo apt-get install libgtk2.0-dev libgtk-3-dev
    # OpenCV中的许多操作(即矩阵操作)可以通过安装一些额外的依赖关系进一步优化
    sudo apt-get install libatlas-base-dev gfortran
    # 安装Python 2.7和Python 3头文件,以便我们可以用Python绑定来编译OpenCV
    sudo apt-get install python2.7-dev python3-dev
    

    如果是新安装的操作系统,那么这些版本的Python可能已经是最新版本了(终端可以看到)。

    ③下载OpenCV源代码

    现在我们已经安装了依赖项,从官方的OpenCV仓库中获取OpenCV 的 4.1.2归档。

    cd ~
    wget -O opencv.zip https://github.com/Itseez/opencv/archive/4.1.2.zip
    unzip opencv.zip
    

    我们需要完整安装 OpenCV 3(例如,可以访问SIFT和SURF等功能),因此我们还需要获取opencv_contrib存储库。

    wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/4.1.2.zip
    unzip opencv_contrib.zip
    

    注意:确保 opencv和 opencv_contrib版本相同。

    如果版本号不匹配,那么可能会遇到编译时错误或运行时错误。

    ④Python 2.7或Python 3

    在我们开始在我们的Raspberry Pi 3上开始编译OpenCV之前

    首先需要安装 Python包管理器pip:

    wget https://bootstrap.pypa.io/get-pip.py
    sudo python get-pip.py
    sudo python3 get-pip.py
    

    可能会收到一条消息,指出在发出这些命令时pip已经是最新的,但最好不要跳过这一步 。

    接下来安装virtualenv和 virtualenvwrapper

    首先,了解虚拟环境是一种特殊的工具,通过为每个环境创建独立的,独立的 Python环境来保持不同项目所需的依赖关系,这一点很重要。

    总之,它解决了“Project X取决于版本1.x,但项目Y需要4.x”的困境

    安装python虚拟机

    sudo pip install virtualenv virtualenvwrapper
    sudo rm -rf ~/.cache/pip 
    

    配置~/.profile,添加内容:

    # virtualenv and virtualenvwrapper
    export WORKON_HOME=$HOME/.virtualenvs
    export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
    source /usr/local/bin/virtualenvwrapper.sh
    

    使之生效

    source ~/.profile
    

    使用Python3 安装虚拟机

    mkvirtualenv cv -p python3
    

    虚拟机完成安装之后,后续的所有操作全部在虚拟机中进行。按照教程的说明,一定要看清楚命令行前面是否有(cv),以此作为是否在虚拟机的判断!
    需要重新进入虚拟机,可运行下面的命令

    source ~/.profile
    workon cv
    

    再次提醒:后续所有操作均在虚拟机中
    安装numpy

    pip install numpy
    

    ⑤编译OpenCV

    cd ~/opencv-4.1.2/
    mkdir build
    cd build
    cmake -D CMAKE_BUILD_TYPE=RELEASE 
        -D CMAKE_INSTALL_PREFIX=/usr/local 
        -D INSTALL_PYTHON_EXAMPLES=ON 
        -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-4.1.2/modules 
        -D BUILD_EXAMPLES=ON ..
    

    编译之前配置交换空间大小

    在开始编译过程之前,应 增加交换空间的大小。这使OpenCV可以使用 Raspberry PI的所有四个内核进行编译,而不会由于内存问题而挂起编译。

    把交换空间交换空间增大到 CONF_SWAPSIZE=1024

    # 虚拟机中sudo才可以修改
    sudo nano /etc/dphys-swapfile  
    sudo /etc/init.d/dphys-swapfile stop
    sudo /etc/init.d/dphys-swapfile start
    # 开始编译(顺利的话1个多小时就可以编译完,运气不好的话遇到很多坑可能一天都...)
    make  
    

    编译过程好费时间长而且一波三折,遇到了一些坑(好多ERROR),重新烧录了好几次备份系统(差点自闭QAQ),但好在都一一解决了,遇到问题详情及解决办法在(5)。

    ⑥安装OpenCV

    sudo make install
    sudo ldconfig
    

    检查OpenCV的安装位置

    ls -l /usr/local/lib/python3.7/site-packages/
    cd ~/.virtualenvs/cv/lib/python3.7/site-packages/
    ln -s /usr/local/lib/python3.7/site-packages/cv2 cv2
    

    验证安装

    source ~/.profile 
    workon cv
    python
    import cv2
    cv2.__version__
    

    关于opencv的编译安装,可以参考

    (2)使用opencv和python控制树莓派的摄像头

    安装picreame

    source ~/.profile 
    workon cv 
    pip install "picamera[array]"
    

    拍照测试

    按照教程给的示例代码,验证Python控制摄像头拍照的效果,增加示例代码中sleep的时间,让摄像头曝光时间增加,拍照效果比较好。

    示例代码

    # import the necessary packages
    from picamera.array import PiRGBArray
    from picamera import PiCamera
    import time
    import cv2
     
    # initialize the camera and grab a reference to the raw camera capture
    camera = PiCamera()
    rawCapture = PiRGBArray(camera)
     
    # allow the camera to warmup
    # 此处把0.1改成了5
    time.sleep(5)
     
    # grab an image from the camera
    camera.capture(rawCapture, format="bgr")
    image = rawCapture.array
     
    # display the image on screen and wait for a keypress
    cv2.imshow("Image", image)
    cv2.waitKey(0)
    

    image-20200602183951804

    (3)利用树莓派的摄像头实现人脸识别

    安装依赖库dlib,face_recognition

    在命令行输入:

    source ~/.profile 
    workon cv 
    pip install dlib
    pip install face_recognition
    

    image-20200602203935077

    切换到放有要加载图片和python代码的目录下

    image-20200602203058657

    ①facerec_on_raspberry_pi.py

    示例代码如下:

    # This is a demo of running face recognition on a Raspberry Pi.
    # This program will print out the names of anyone it recognizes to the console.
    # To run this, you need a Raspberry Pi 2 (or greater) with face_recognition and
    # the picamera[array] module installed.
    # You can follow this installation instructions to get your RPi set up:
    # https://gist.github.com/ageitgey/1ac8dbe8572f3f533df6269dab35df65
    
    import face_recognition
    import picamera
    import numpy as np
    
    # 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)
    
    # Load a sample picture and learn how to recognize it.
    print("Loading known face image(s)")
    image = face_recognition.load_image_file("test.jpg")
    face_encoding = face_recognition.face_encodings(image)[0]
    
    # Initialize some variables
    face_locations = []
    face_encodings = []
    
    while True:
    
        print("Capturing image.")
        # Grab a single frame of video from the RPi camera as a numpy array
        camera.capture(output, format="rgb")
    
        # Find all the faces and face encodings in the current frame of video
        face_locations = face_recognition.face_locations(output)
    
        print("Found {} faces in image.".format(len(face_locations)))
        face_encodings = face_recognition.face_encodings(output, face_locations)
    
        # Loop over each face found in the frame to see if it's someone we know.
        for face_encoding in face_encodings:
    
            # See if the face is a match for the known face(s)
            match = face_recognition.compare_faces([face_encoding], face_encoding)
            name = "<Unknown Person>"
    
            if match[0]:
                name = "Trump"
            print("I see someone named {}!".format(name))
    

    一开始摄像头没有对准照片,后面照片移入摄像头拍摄范围,可以看到识别成功。

    • test.jpg用于上传转换格式提取特征值保存

    • Trump.jpg用于测试是否准确识别出Trump

    • Kim Jong Eun.jpg用于测试是否准确识别出Unknown Person

    image-20200602210528396

    测试test2.jpg并查看是否准确识别Trump

    img

    image-20200602211737621

    当照片切换到Kim Jong Eun.jpg,可以看到识别出一张人脸而且是Unknown Person

    img

    image-20200602213050009

    ②facerec_from_webcam_faster.py

    示例代码如下:

    import face_recognition
    import cv2
    import numpy as np
    
    # This is a demo of running face recognition on live video from your webcam. It's a little more complicated than the
    # other example, but it includes some basic performance tweaks to make things run a lot faster:
    #   1. Process each video frame at 1/4 resolution (though still display it at full resolution)
    #   2. Only detect faces in every other frame of video.
    
    # PLEASE NOTE: This example requires OpenCV (the `cv2` library) to be installed only to read from your webcam.
    # OpenCV is *not* required to use the face_recognition library. It's only required if you want to run this
    # specific demo. If you have trouble installing it, try any of the other demos that don't require it instead.
    
    # Get a reference to webcam #0 (the default one)
    video_capture = cv2.VideoCapture(0)
    
    # Load a sample picture and learn how to recognize it.
    Trump_image = face_recognition.load_image_file("Trump.jpg")
    Trump_face_encoding = face_recognition.face_encodings(Trump_image)[0]
    
    # Load a second sample picture and learn how to recognize it.
    Kim_Jong_Eunimage = face_recognition.load_image_file("Kim_Jong_Eun.jpg")
    Kim_Jong_Eunface_encoding = face_recognition.face_encodings(Kim_Jong_Eunimage)[0]
    
    # Create arrays of known face encodings and their names
    known_face_encodings = [
        Trump_face_encoding,
        Kim_Jong_Eunface_encoding
    ]
    
    known_face_names = [
        "Trump",
        "Kim_Jong_Eun"
    ]
    
    
    
    # Initialize some variables
    face_locations = []
    face_encodings = []
    face_names = []
    
    process_this_frame = True
    
    while True:
    
        # Grab a single frame of video
        ret, frame = video_capture.read()
    
        # Resize frame of video to 1/4 size for faster face recognition processing
        small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
    
        # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
        rgb_small_frame = small_frame[:, :, ::-1]
    
        # Only process every other frame of video to save time
        if process_this_frame:
    
            # Find all the faces and face encodings in the current frame of video
            face_locations = face_recognition.face_locations(rgb_small_frame)
            face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
    
            face_names = []
            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)
                name = "Unknown"
    
                # # If a match was found in known_face_encodings, just use the first one.
                # if True in matches:
                #     first_match_index = matches.index(True)
                #     name = known_face_names[first_match_index]
                # Or instead, use the known face with the smallest distance to the new face
                face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
                best_match_index = np.argmin(face_distances)
                if matches[best_match_index]:
                    name = known_face_names[best_match_index]
    
                face_names.append(name)
    
        process_this_frame = not process_this_frame
    
        # Display the results
        for (top, right, bottom, left), name in zip(face_locations, face_names):
            # Scale back up face locations since the frame we detected in was scaled to 1/4 size
            top *= 4
            right *= 4
            bottom *= 4
            left *= 4
    
            # Draw a box around the face
            cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
    
            # Draw a label with a name below the face
            cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
            font = cv2.FONT_HERSHEY_DUPLEX
            cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
    
        # Display the resulting image
        cv2.imshow('Video', frame)
    
        # Hit 'q' on the keyboard to quit!
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    
    # Release handle to the webcam
    video_capture.release()
    cv2.destroyAllWindows()
    

    验证识别成功

    image-20200602225447539

    image-20200603124349072

    image-20200602225640221

    因为左边的人物图像没有上传提取特征值保存,所以识别为unknown,识别成功

    image-20200602225858969

    (4)结合微服务的进阶任务

    ①安装Docker

    下载安装脚本

    curl -fsSL https://get.docker.com -o get-docker.sh
    

    image-20200603113918613

    运行安装脚本(阿里云镜像)

    sh get-docker.sh --mirror Aliyun
    

    查看docker版本,验证是否安装成功

    image-20200603114217061

    添加用户到docker组

    sudo usermod -aG docker pi 
    

    重新登陆让用户组生效

    exit 
    ssh pi@raspiberry
    

    重启之后,docker指令之前就不需要加sudo了

    image-20200603114547044

    ②定制opencv镜像

    拉取镜像

    docker pull sixsq/opencv-python
    

    image-20200603115227482

    创建并运行容器

    docker run -it sixsq/opencv-python /bin/bash
    

    在容器中,用pip3安装 "picamera[array]",dlib和face_recognition

    pip3 install "picamera[array]" 
    pip3 install dlib 
    pip3 install face_recognition
    exit
    

    commit镜像image-20200603124450631

    自定义镜像

    image-20200603142014724

    • Dockerfile
    FROM opencv1
    RUN mkdir /myapp
    WORKDIR /myapp
    COPY myapp .
    

    构建镜像

    docker build -t opencv2 .
    

    image-20200603142347801

    查看镜像

    image-20200603142411985

    ③运行容器执行facerec_on_raspberry_pi.py

    docker run -it --device=/dev/vchiq --device=/dev/video0 --name myopencv opencv2
    python3 facerec_on_raspberry_pi.py
    

    image-20200603162834905

    image-20200603143857123

    ④选做:在opencv的docker容器中跑通步骤(3)的示例代码facerec_from_webcam_faster.py

    在Windows系统中安装Xming

    开启树莓派的ssh配置中的X11

    image-20200603152147599

    image-20200603153225966

    查看DISPLAY环境变量值

    printenv
    

    image-20200603154316591

    编写run.sh

    #sudo apt-get install x11-xserver-utils
    xhost +
    docker run -it 
            --net=host 
            -v $HOME/.Xauthority:/root/.Xauthority 
            -e DISPLAY=:10.0  
            -e QT_X11_NO_MITSHM=1 
            --device=/dev/vchiq 
            --device=/dev/video0 
            --name facerecgui 
            opencv2 
    	python3 facerec_from_webcam_faster.py
    

    打开终端,运行run.sh

    sh run.sh
    

    可以看到在windows的Xvideo可以正确识别人脸。

    image-20200603154818505

    image-20200603155022452

    参考教程

    (5)遇到的问题及解决方法

    问题1:环境/Users/myuser/.virtualenvs/iron不包含激活脚本

    在使用Python3 安装虚拟机的时候出现下图的安装错误

    卸载virtualenv和virtualenvwrapper

    sudo pip3 uninstall virtualenv virtualenvwrapper
    

    看到virtualenvwrapper我安装的版本是5.0.0。

    检查了PyPi,它仍然是4.8.4版。

    重新安装了两者并指定了版本

    sudo pip3 install virtualenv virtualenvwrapper=='4.8.4'
    

    我获取了.bashrc的源代码,其中附加了设置:

    VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
    VIRTUALENVWRAPPER_VIRTUALENV=/usr/local/bin/virtualenv
    export PATH=/usr/local/bin:$PATH
    export WORKON_HOME=~/.virtualenvs
    source /usr/local/bin/virtualenvwrapper.sh
    

    Python3重新安装虚拟机

    mkvirtualenv cv -p python3
    

    参考教程

    Error: Environment /Users/myuser/.virtualenvs/iron does not contain activation script

    ERROR: Environment '/home/pi/.virtualenvs/cv' does not contain an activate script

    问题2:fatal error: features2d/test/test_detectors_regression.impl.hpp: 没有那个文件或目录

    头文件include路径不对,解决方法如下:

    将opencv-4.1.2/modules/features2d/test/文件下的

    • test_descriptors_regression.impl.hpp
    • test_detectors_regression.impl.hpp
    • test/test_detectors_invariance.impl.hpp
    • test_descriptors_invariance.impl.hpp
    • test_invariance_utils.hpp

    拷贝到opencv_contrib-4.1.0/modules/xfeatures2d/test/文件下。

    同时,将opencv_contrib-4.1.2/modules/xfeatures2d/test/test_features2d.cpp文件下的

    #include "features2d/test/test_detectors_regression.impl.hpp"
    #include "features2d/test/test_descriptors_regression.impl.hpp"
    

    改成:

    #include "test_detectors_regression.impl.hpp"
    #include "test_descriptors_regression.impl.hpp"
    

    之后编译过程中可能还会遇到类似问题,也是按照同样的做法。

    参考博客

    在Ubuntu16.04上编译opencv4.1.0-gpu带contrib版本碰到的问题

    问题3: error: 'CODEC_FLAG_GLOBAL_HEADER' was not declared in this scope

    解决方法:

    在 /home/pi/opencv-4.1.2/modules/videoio/src/cap_ffmpeg_impl.hpp 里最顶端添加

    #define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22) 
    #define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER 
    #define AVFMT_RAWPICTURE 0x0020 
    

    参考博客

    Ubuntu 源码安装opencv320 报错 error: 'CODEC_FLAG_GLOBAL_HEADER' was not declared in this scope

    问题4: fatal error: boostdesc_bgm.i: 没有那个文件或目录#include "boostdesc_bgm.i"

    解决方法:

    需要下列文件

    • boostdesc_bgm.i

    • boostdesc_bgm_bi.i

    • boostdesc_bgm_hd.i

    • boostdesc_lbgm.i

    • boostdesc_binboost_064.i

    • boostdesc_binboost_128.i

    • boostdesc_binboost_256.i

    • vgg_generated_120.i

    • vgg_generated_64.i

    • vgg_generated_80.i

    • vgg_generated_48.i

    网上下载压缩包( 提取码:p50x )拷贝到opencv_contrib/modules/xfeatures2d/src/目录下并且解压**

    参考博客

    安装OpenCV时提示缺少boostdesc_bgm.i文件的问题解决方案

    (6)分工协作及总结

    小组成员名单

    学号 姓名 分工
    071703428 叶梦晴 查阅资料、实际操作及博客撰写
    031702444 李尚佳 实际操作、解决问题及博客撰写
    181700134 宋娟 查阅资料及提供代码

    在线协作

    ①通过TeamViewer远程控制有树莓派同学的电脑进行实际操作

    ②通过QQ语音和文件传输分享博客资料和沟通

    image-20200603171411247

    image-20200603170043335

    ③实验小结

    本次实验学习了如何使用opencv和python控制树莓派的摄像头、利用树莓派的摄像头实现人脸识别以及opencv的docker容器中实现了人脸识别,整体操作下来没有特别大无法解决的问题。就是在搭建opencv库时,因为各种错误(大大小小的坑踩了个遍,环境重新烧录了好几遍QAQ),好几次编译进度条都到不了100%,花了很多很多的时间,在线协作和学习理论知识以及实践操作合计大概有20h,还有其他一些小问题都记录在上面了。通过这次实验体会到树莓派的用处真的很大,而且使用起来也真的很方便,期待下次能做出一个有创意又有意思的实验!

  • 相关阅读:
    跨浏览器右键复制实现
    在eclipse里如何快速定位到某一行?
    为数据库中的表添加字段步骤
    一键安装openstack juno 之controller node.
    Linux的/etc/services文件的作用?
    docker and ssh issues
    yum change source repo centos共存安装sun jdk6和jdk7
    random and password 在Linux下生成crypt加密密码的方法,shell 生成指定范围随机数与随机字符串
    OpenStack,ceph
    那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)[zz]
  • 原文地址:https://www.cnblogs.com/signifyu/p/13038913.html
Copyright © 2011-2022 走看看