• Raspberry Pi 4B 使用OpenCV访问摄像头picamera模块


    1.OpenCV安装

    说到OpenCV的安装,我想做人脸识别,网上找了很多教程,都涉及到OpenCV,而很多教程是基于Adrian Rosebrock的这篇教材Raspbian Stretch: Install OpenCV 3 + Python on your Raspberry Pi
    刚刚看到这篇教程的时候,着实被它的流程吓到了,步骤确实很多,以前装P4开发环境的经历告诉我,这个过程一定不会很顺利。
    于是我想按照这个教程复现一遍。

    (1)安装依赖

    $ sudo apt-get update && sudo apt-get upgrade
    $ sudo apt-get install build-essential cmake pkg-config
    $ sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
    $ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
    $ sudo apt-get install libxvidcore-dev libx264-dev
    $ sudo apt-get install libgtk2.0-dev libgtk-3-dev
    $ sudo apt-get install libatlas-base-dev gfortran
    $ sudo apt-get install python2.7-dev python3-dev
    

    刚开始我是在现有的Raspberry Pi系统上直接安装的,这之前已经配好了网站服务器、FTP服务器等前序博客所做的事情,系统已经不是那么“干净”了。于是我运行上面第三条命令时就报错了,提示要安装的xxx依赖于xxx,但是xxx不会被安装。百度了很多方法,都没有办法解决。差点就想放弃了,第二天决定重新烧录一个干净的系统,并且做好系统备份(很重要!!)
    重新烧录的系统果然“干净”,一路顺利,完成依赖的安装。

    (2)下载OpenCV源码

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

    对网速要求比较高,所幸学校的网络比较快。但是下载完毕,运行unzip解压时报错:Archive: opencv.zip End-of-central-directory signature not found.  Either this file is not a zipfile, or it constitutes one disk of a multi-part archive. In the latter case the central directory and zipfile comment will be found on the last disk(s) of this archive.
    按照网上的方法试着用jar解压,可以成功,暂时没有什么问题了。

    (3)安装pip

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

    (4)安装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
    

    (5)编译OpenCV

    $ cd ~/opencv-3.3.0/
    $ 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-3.3.0/modules 
        -D BUILD_EXAMPLES=ON ..
    

    按照教程提示,编译前检查Python相关配置,结果发现除了Interpreter,其他信息都没有。。。
    我按照教程的建议,再三确认了的确在虚拟环境中,然而无济于事。。。
    又想放弃了。
    第三天,我突然想也许是OpenCV版本太久了,我到Github上看,最新的版本已经到了4.1.2,而且教程中也说了可以把3.3.0改成最新的版本。那既然其他环节都是最新的,那这个相应的也最新吧。于是我重新下载了4.1.2,这次unzip也十分顺利!
    再次运行编译前的检查,这次没有问题了。

    编译前,按照教程,增大了交换空间CONF_SWAPSIZE=1024

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


    安装OpenCV

    $ sudo make install
    $ sudo ldconfig
    

    之后按照教程,检查OpenCV的安装位置,然而按照教程的命令输入,发现是空的!于是我去核对了一下编译前检查的结果,发现我的Python是3.7而不是教程用的3.5,问题解决!同时,我装好的文件名只有cv,没有后面的so

    $ 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
    


    (6)验证安装

    $ source ~/.profile 
    $ workon cv
    $ python
    >>> import cv2
    >>> cv2.__version__
    '4.1.2'
    >>>
    

    成功了!记得备份系统!

    2.使用OpenCV和Python控制摄像头模块

    (1)picamera模块安装

    之后继续按照作者的另一个教程Accessing the Raspberry Pi Camera with OpenCV and Python完成摄像头模块picamera安装,摄像头的初始配置之前已经完成,再此不再赘述。
    开启虚拟机

    $ source ~/.profile
    $ workon cv
    

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

    $ pip install "picamera[array]"
    

    (2)在Python代码中导入OpenCV控制摄像头

    按照教程给的示例代码,验证了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
    time.sleep(3) #此处把0.1改成了3
     
    # 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)
    

    不得不说,这个大神写的教程确实很赞。建议用“干净”的系统安装,可以适当提高OpenCV的版本。编译过程很长,万一失败了,真的很打击积极性,所幸成功了。

    3.Raspberry Pi 的人脸识别

    • 到此为止,我们已经完成在Raspberry Pi上安装OpenCV和摄像头模块picamera,并且成功用导入了opencv的python代码控制picamera,实现了拍摄一张照片的demo。在此基础上,还可以做的事很多,比如人脸识别。

    • 人脸识别可以用face_recogniztion这个开源模块。

    • 在前面创建的python虚拟环境cv中安装dlib和face_recognition,使得能够在cv中运行face_recognition。之后如果不进入虚拟环境cv,那么就无法运行face_recognition。

    $ pip install dlib
    $ pip install face_recognition
    

    • 运行GitHub上face_recognition仓库下的代码
      该示例是一个简单的程序,仅调用了picamera,未用到opencv模块。将代码保存在py文件中,在虚拟机cv中运行,并保证代码中的预先加载的人脸信息和代码py文件在同一目录。程序先获取特定脸部信息,之后不断读取摄像头当前捕获的人像,显示人像数,并和已有脸部信息进行比对,如果没有匹配就是unknown person,如果匹配,就显示人名。
      运行结果:

    • 同一个代码仓库下的另一个示例
      该示例引入opencv来处理图像信息,可以实时显示当前摄像头识别到的人脸信息

    4.使用OpenCV的Docker容器运行运行人脸识别代码

    OpenCV安装过于复杂,使用OpenCV容器直接省去了安装步骤。

    • Docker镜像: sixsq/opencv-python,支持ARM
    • 拉取基础镜像后,进入容器,安装picamera[array]、dlib和face_recognition,commit更新容器建立新的镜像
    • 以上述新的镜像为基础,编写Dockerfile,设置启动时执行的命令:ENTRYPOINT["python3"],重新build最终的镜像
    • 启动容器
    $ docker run -it -v [本地代码目录]:[容器工作目录] --device=/dev/vchiq --device=/dev/video0 --name [容器名] [镜像名] [人脸识别python代码]
    
    • 运行结果:

    虽然容器省去了费时费力的安装配置,但是也会遇到新的问题:

    • 直接以sixsq/opencv-python做Dockerfile,RUN安装face_recognition报错了,于是选择直接进到容器内安装再更新
    • 运行容器报错fail to open vchiq instance,讨论后发现需要在启动容器时使用参数--device=/dev/vchiq解决,具体见上述命令,让容器使用Raspberry Pi的摄像头
    • 如果希望通过容器运行人脸识别相关的GUI图形化程序,即上面的第二个例子,直接使用之前的方法是会报错VIDEOIO ERROR: V4L: can't open camera by index 0,这可以通过--device=/dev/video0解决,另一个报错关键的报错是: cannot connect to X server

      经过和学生探讨,得到解决方法:参考Docker运行GUI软件的方法,添加/tmp/.X11-unix挂载以及DISPLAY环境变量,并且用xhost命令允许所有用户访问X11服务,之后出错X Error:BadDrawable (individ Pixmap or Window parameter 9),还要添加QT_X11_NO_MITSHM=1环境变量,最终修改容器启动shell脚本如下:

    (1)VNC访问Raspberry Pi,在树莓派上直接启动

    #sudo apt-get install x11-xserver-utils
    xhost +
    docker run -it 
    	-v [本地代码目录]:[容器工作目录] 
    	-v /tmp/.X11-unix:/tmp/.X11-unix 
    	-e DISPLAY=$DISPLAY 
    	-e QT_X11_NO_MITSHM=1 
      	--device=/dev/vchiq 
    	--device=/dev/video0 
    	--name [容器名] 
    	[镜像名] 
    	[人脸识别python代码]
    

    (2)ssh访问Raspberry Pi,在pc上远程启动

    #sudo apt-get install x11-xserver-utils
    xhost +
    docker run -it 
            -v [本地代码目录]:[容器工作目录] 
            --net=host 
            -v $HOME/.Xauthority:/root/.Xauthority 
            -e DISPLAY=:10.0  
            -e QT_X11_NO_MITSHM=1 
            --device=/dev/vchiq 
            --device=/dev/video0 
            --name [容器名] 
            [镜像名] 
            [人脸识别python代码]
    

    VNC访问Raspberry Pi的运行结果:

    SSH访问Raspberry Pi的运行结果:

  • 相关阅读:
    maven的安装教程
    Spring 历史及设计理念
    MySQL Connector / Python
    LDAP & implementation
    RESTful levels & HATEOAS
    事务隔离级别
    cookie 和 session
    正则表达式验证器regex validator
    hello2部分代码分析
    filter
  • 原文地址:https://www.cnblogs.com/fjlinww/p/11956264.html
Copyright © 2020-2023  润新知