• 2020系统综合实践(七)第15组


    实验一、在树莓派中安装opencv库

    步骤1:扩展文件系统。第一件事就是扩展文件系统,以包括microSD卡上的所有可用空间:

     sudo raspi-config
    

    完成以上操作后,执行下面命令来重新启动pi:

    sudo reboot 
    

    重新启动后,文件系统应已扩展为包括micro-SD卡上的所有可用空间。可以通过执行以下命令来验证磁盘是否已扩展并检查输出:

    df -h
    

    但是,即使扩展了文件系统,我也已经使用了15GB卡中的46%。因此,可以删除LibreOffice和Wolfram引擎以释放Pi上的一些空间:

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

    前后对比,多了2GB。做到这里基本没有什么问题。

    步骤2:安装依赖项

    在安装依赖包之前,建议先进行换清华源。不然很容易下着下着就崩了,很影响实验心情说实话。
    注意:在更新前一定要安装 aptitude ,不然后面你可能会被“无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系”这样的错误折磨发疯,aptitude 与 apt-get 一样,是 Debian 及其衍生系统中功能极其强大的包管理工具。与 apt-get 不同的是,aptitude 在处理依赖问题上更佳一些。举例来说,aptitude 在删除一个包时,会同时删除本身所依赖的包。这样,系统中不会残留无用的包,整个系统更为干净。树莓派在换源后,apt-get install 安装软件, 会报“无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系”。这个错误出现的主要原因是,系统中已经安装了被依赖的包的高版本,并且版本高于所要求的这个版本,不匹配导致安装失败。虽然这种报错可以手动安装指定版本的软件包,但是各种互相依赖的一环套一环,会出现各种新的报错。

    sudo apt-get install aptitude
    

    下载完aptitude之后,准备换源。执行以下命令,进行编辑系统源文件:

    sudo nano /etc/apt/sources.list
    

    将初始的源使用#注释掉,添加如下两行清华的镜像源。【注意】这里的树莓派系统是Raspbian-buster系统,在写系统源链接时要注意是buster,网上很多教程都是之前stretch版本,容易出错!

    deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi
    deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi
    

    再更改系统源:

    sudo nano /etc/apt/sources.list.d/raspi.list
    

    用#注释掉原文件内容,用以下内容取代:

    deb http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ buster main ui
    deb-src http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ buster main ui
    

    然后执行以下操作完成换源:

    sudo apt-get update
    sudo apt-get upgrade
    

    可能会出现以下情况:


    我直接跳过了,不理它。

    这个部分参考这篇文章树莓派4B(Raspbian-buster系统)换清华源并更换系统源

    然后安装开发工具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
    

    做到这里,这一部分遇到问题如下:
    问题一:在参考Raspbian Stretch: Install OpenCV 3 + Python on your Raspberry Pi这篇文档,执行sudo apt-get update && sudo apt-get upgrade 来更新所有软件包时,下载速度贼慢,最后挂掉。(在没换清华源之前,我是用了阿里源,不知道是不是我阿里源没配置好的问题)。

    解决方案:其实在换清华源之前,我是使用的是阿里源,然后换成了中科大源,可是在接下来遇到了问题,不得不再一次换源。(我觉得应该是我换中科大源的时候没配置好)。所以建议,一步到位,按我上面的方法直接换成清华源。
    问题二:在没换清华源以及下载aptitude之前,执行sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev命令后,出现包与包之间依赖的问题。

    解决方案:先下载aptitude,再换成清华源,就解决了。清华源真香!

    步骤#3:下载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存储库。注意:确保 opencv和opencv_contrib版本相同。如果版本号不匹配,那么可能会遇到编译时错误或运行时错误。

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


    这里我在执行unzip xxx.zip的时候出现问题
    问题三:

    解决方案:参考这篇博客在Linux中使用unzip打开zip文件失败。也有博客写着下载7zip来解压.zip文件,我这个方法试了,结果出现新的问题,所以不建议采用。

    步骤4:Python 2.7或Python 3?

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

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

    接下来安装virtualenv和 virtualenvwrapper,这里与文档给出的命令有些不一样,因为按文档的命令执行会出现一些问题,建议改成下面命令。

    sudo pip3 install virtualenv virtualenvwrapper=='4.8.4'
    sudo rm -rf ~/.cache/pip 
    

    配置~/.profile,添加内容:(这里建议下载一个VIM,方便编辑)

    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
    

    执行上面的命令,我又出问题了:
    问题四:安装超时。

    解决方案:参考博客python pip安装第三方库超时问题
    更改命令:

    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy
    

    步骤5:编译并安装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。

    注意:vim保存修改只读文件命令为(:w !sudo tee %)。在终端输入的时候没有括号。

    # 虚拟机中sudo才可以修改
    sudo nano /etc/dphys-swapfile  
    sudo /etc/init.d/dphys-swapfile stop
    sudo /etc/init.d/dphys-swapfile start
    # 开始编译(近2个小时吧)
    make  
    


    步骤6:完成在Pi上安装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__
    

    最后打开你的 /etc/dphys-swapfile 然后把 CONF_SWAPSIZE改回100。

    实验二、使用opencv和python控制树莓派的摄像头

    1.安装picreame

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

    2.实例代码

    test_image.py

    # 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
    time.sleep(2)
    
    # 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)
    

    实验三、利用树莓派的摄像头实现人脸识别

    1、安装依赖库dlib,face_recognition

    pip install dlib
    pip install face_recognition
    


    2、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)")
    Lilianjie_image = face_recognition.load_image_file("Lilianjie.jpg")
    Lilianjie_face_encoding = face_recognition.face_encodings(Lilianjie_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([Lilianjie_face_encoding], face_encoding)
            name = "<Unknown Person>"
    
            if match[0]:
                name = "Lilianjie"
            print("I see someone named {}!".format(name))
    
    

    3、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.
    Lilianjie_image = face_recognition.load_image_file("Lilianjie.jpg")
    Lilianjie_face_encoding = face_recognition.face_encodings(Lilianjie_image)[0]
    
    # Load a second sample picture and learn how to recognize it.
    Guanzhiling_image = face_recognition.load_image_file("Guanzhiling.jpg")
    Guanzhiling_face_encoding = face_recognition.face_encodings(Guanzhiling_image)[0]
    
    # Create arrays of known face encodings and their names
    known_face_encodings = [
        Lilianjie_face_encoding,
        Guanzhiling_face_encoding
    ]
    known_face_names = [
        "Lilianjie",
        "Guanzhiling"
    ]
    
    # 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()
    

    实验四、结合微服务的进阶任务

    安装Docker

    下载安装脚本

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

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

    sh get-docker.sh --mirror Aliyun
    

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

    添加用户到docker组,然后重新登陆让用户组生效

    sudo usermod -aG docker pi
    

    定制opencv镜像

    拉取镜像

    docker pull sixsq/opencv-python
    

    创建并运行容器

    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镜像

    自定义镜像

    Dockerfile

    FROM opencv1
    RUN mkdir /my
    WORKDIR /my
    COPY my .
    

    构建镜像

    docker build -t opencv2 .
    

    运行容器执行facerec_on_raspberry_pi.py

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

    选做:

    环境准备

    在Windows系统中安装Xming和Putty安装好后,先打开Xming,然后打开Putty,开启树莓派的ssh配置中的X11
    打开Putty后,把树莓派的IP地址填在下面这一栏里,端口用默认的就行了

    查看DISPLAY环境变量值

    注意:这个查看是在用Putty打开的窗口上查看到的,若直接在树莓派里的终端看,看到就是"DISPLAY=localhost:10.0"

    printenv
    

    在用Putty打开的窗口上编写run.sh(路径在树莓派中的docker1文件夹

    #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
    

    小组分工

    学号 姓名 分工
    031502115 黄 臻 查找资料,解决问题
    031702243 杨成锦 动手操作,解决问题
    031702218 覃鸿浩 查找资料,解决问题
  • 相关阅读:
    cmd常用命令
    快捷键
    leetcode:Sort List(一个链表的归并排序)
    leetcode:Merge Two Sorted Lists(有序链表的归并)
    leetcode:Search for a Range(数组,二分查找)
    leetcode:Search a 2D Matrix(数组,二分查找)
    实时操作系统与分时操作系统
    第四章函数作业题,函数模板
    第四章函数作业题,函数的重载
    第四章函数作业题,内置函数
  • 原文地址:https://www.cnblogs.com/ycj202595/p/13057520.html
Copyright © 2020-2023  润新知