妈妈晚上平静地入睡-我们为Raspbian'a收集OpenCV

最近几周对我们的团队来说很艰难。 OpenCV 4已发布 ,并与之一起为Intel的OpenVINO工具包 R4(包括OpenCV)做准备。 您可能认为,我已经分散了一段时间,我会像往常一样关注OpenCV论坛和用户评论,在这里您可以说OpenCV不是物联网,在Raspberry Pi下它足以组装-没有足够的焊料可一make -j2地投入make -j2如果您幸运的话,早晨将准备就绪。


因此,我建议携手合作,看看如何为一个运行在ARM处理器上的32位操作系统组装OpenCV库,如何使用具有出色CPU架构的64位OS计算机资源。 巫术 交叉编译,否则不会!


问题陈述


直接在板上进行编译(通常称为本地编译)确实很费力,因此在这里,我们将考虑一种构建项目的方法,该项目可以使功能更强大的计算设备(称为主机)为小亲戚准备二进制文件。 而且,两台机器可以具有不同的CPU架构。 这是交叉编译。


因此,要准备塞满OpenCV的树莓派,我们需要:


  • Ubuntu 16.04镜像docker尸体
  • 主机比Raspberry Pi更强大(否则,有什么意义,不是吗?)
  • 用于ARMhf的交叉编译器以及相应体系结构的库

构建OpenCV的整个过程将在主机上进行。 我在家使用Ubuntu。 使用其他版本的Linux,应该不会出现播放问题。 对于Windows用户-我衷心希望不要放弃并尝试自己解决这个问题。


安装Docker


大约一周前,我开始与docker结识,因此添加美味的食盐和语法糖。 对您我来说,三个要素就足够了-Dockerfile,映像和容器的概念。


Docker本身是一种用于创建和复制具有必需组件集的任何操作系统的配置的工具。 Dockerfile是通常在主机上使用的一组shell命令,但是在这种情况下,它们都适用于所谓的docker映像。


为了安装docker,请考虑最简单的方法:通过apt-get交付服务订购软件包:


 sudo apt-get install -y docker.io 

我们将为docker守护程序提供它所要求的一切,并从系统注销(注意相应地登录)。


 sudo usermod -a -G docker $USER 

准备工作区


最常见的准备工作是Raspberry Pi(在我的情况下为RPI 2 Model B)是带有Raspbian(基于Debian)操作系统的ARMv7 CPU。 我们将基于Ubuntu 16.04创建一个docker映像,在其中我们将报告交叉编译器,军队库并在同一位置收集OpenCV。


在我们的Dockerfile所在的位置创建一个爸爸:


 mkdir ubuntu16_armhf_opencv && cd ubuntu16_armhf_opencv touch Dockerfile 

添加有关apt-get软件包安装程序的基本操作系统和armhf体系结构的信息:


 FROM ubuntu:16.04 USER root RUN dpkg --add-architecture armhf RUN apt-get update 

请注意,诸如FROM ...RUN ...类的命令是Dockerfile语法,并写入创建的Dockerfile测试文件中。


让我们回到父目录ubuntu16_armhf_opencv并尝试创建我们的ubuntu16_armhf_opencv镜像:


 docker image build ubuntu16_armhf_opencv 

在执行apt-get update命令期间,应导致您看到以下类型的Err:[] [url] xenial[-] armhf Packages


 Ign:30 http://archive.ubuntu.com/ubuntu xenial-backports/main armhf Packages Ign:32 http://archive.ubuntu.com/ubuntu xenial-backports/universe armhf Packages Err:7 http://archive.ubuntu.com/ubuntu xenial/main armhf Packages 404 Not Found Ign:9 http://archive.ubuntu.com/ubuntu xenial/restricted armhf Packages Ign:18 http://archive.ubuntu.com/ubuntu xenial/universe armhf Packages Ign:20 http://archive.ubuntu.com/ubuntu xenial/multiverse armhf Packages Err:22 http://archive.ubuntu.com/ubuntu xenial-updates/main armhf Packages 404 Not Found Ign:24 http://archive.ubuntu.com/ubuntu xenial-updates/restricted armhf Packages Ign:26 http://archive.ubuntu.com/ubuntu xenial-updates/universe armhf Packages Ign:28 http://archive.ubuntu.com/ubuntu xenial-updates/multiverse armhf Packages Err:30 http://archive.ubuntu.com/ubuntu xenial-backports/main armhf Packages 404 Not Found Ign:32 http://archive.ubuntu.com/ubuntu xenial-backports/universe armhf Packages 

如果查看文件/etc/apt/sources.list那么每个这样的错误都对应/etc/apt/sources.list行,例如:


失误


 Err:22 http://archive.ubuntu.com/ubuntu xenial-updates/main armhf Packages 404 Not Found 

在/etc/apt/sources.list中的行


 deb http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted 

解决方案
分为两部分:


 deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted 

因此,您必须替换几个软件包源。 在我们的泊坞窗中,我们将用一个命令将它们全部替换:


 RUN sed -i -E 's|^deb ([^ ]+) (.*)$|deb [arch=amd64] \1 \2\ndeb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ \2|' /etc/apt/sources.list 

现在, apt-get update应该可以正常工作了。


我们把必要的包裹


我们需要提供主机包,例如gitpython-pipcmakepkg-config以及crossbuild-essential-armhf ,这是一组gcc / g ++交叉编译器( arm-linux-gnueabihf-gccarm-linux-gnueabihf-g++ )和相应架构的系统库:


 RUN apt-get install -y git python-pip cmake pkg-config crossbuild-essential-armhf 

从不同寻常的地方-我们还下载了GTK(用于在highgui模块中绘制窗口),GStreamer和Python,但明确指出了外部体系结构:


 RUN apt-get install -y --no-install-recommends \ libgtk2.0-dev:armhf \ libpython-dev:armhf \ libgstreamer1.0-dev:armhf \ libgstreamer-plugins-base1.0-dev:armhf \ libgstreamer-plugins-good1.0-dev:armhf \ libgstreamer-plugins-bad1.0-dev:armhf 

然后我们克隆并收集,指示必要的标志:


 RUN git clone https://github.com/opencv/opencv --depth 1 RUN mkdir opencv/build && cd opencv/build && \ export PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig && \ cmake -DCMAKE_BUILD_TYPE=Release \ -DOPENCV_CONFIG_INSTALL_PATH="cmake" \ -DCMAKE_TOOLCHAIN_FILE="../opencv/platforms/linux/arm-gnueabi.toolchain.cmake" \ -DWITH_IPP=OFF \ -DBUILD_TESTS=OFF \ -DBUILD_PERF_TESTS=OFF \ -DOPENCV_ENABLE_PKG_CONFIG=ON \ -DPYTHON2_INCLUDE_PATH="/usr/include/python2.7" \ -DPYTHON2_NUMPY_INCLUDE_DIRS="/usr/local/lib/python2.7/dist-packages/numpy/core/include" \ -DENABLE_NEON=ON \ -DCPU_BASELINE="NEON" .. 

在哪里


  • CMAKE_TOOLCHAIN_FILE定义交叉编译过程的cmake文件的路径(设置所需的编译器,限制使用主机库。


  • WITH_IPP=OFF ,-禁用大量依赖。


  • BUILD_TESTS=OFFBUILD_PERF_TESTS=OFF ,禁用测试版本。


  • OPENCV_ENABLE_PKG_CONFIG=ON这样pkg-config可以找到类似GTK的依赖项。 PKG_CONFIG_PATHpkg-config将在其中查找库的正确路径。


  • PYTHON2_INCLUDE_PATHPYTHON2_NUMPY_INCLUDE_DIRS交叉编译python2包装器所需的路径。


  • ENABLE_NEON=ONCPU_BASELINE="NEON" -启用NEON优化。


  • OPENCV_CONFIG_INSTALL_PATH调整文件在install目录中的位置。



cmake执行后,您应注意的主要事情是所有必需的模块都已组装(例如python2):


 -- OpenCV modules: -- To be built: calib3d core dnn features2d flann gapi highgui imgcodecs imgproc java_bindings_generator ml objdetect photo python2 python_bindings_generator stitching ts video videoio -- Disabled: world -- Disabled by dependency: - -- Unavailable: java js python3 -- Applications: tests perf_tests apps -- Documentation: NO -- Non-free algorithms: NO 

并找到了必要的依赖项,例如GTK:


 -- GUI: -- GTK+: YES (ver 2.24.30) -- GThread : YES (ver 2.48.2) -- GtkGlExt: NO -- -- Video I/O: -- GStreamer: -- base: YES (ver 1.8.3) -- video: YES (ver 1.8.3) -- app: YES (ver 1.8.3) -- riff: YES (ver 1.8.3) -- pbutils: YES (ver 1.8.3) -- v4l/v4l2: linux/videodev2.h 

剩下的就是调用makemake install并等待构建完成:


 Successfully built 4dae6b1a7d32 

使用此图像id标记并创建一个容器:


 docker tag 4dae6b1a7d32 ubuntu16_armhf_opencv:latest docker run ubuntu16_armhf_opencv 

我们只需要从容器中抽出组装好的OpenCV。 首先,让我们看一下创建的容器的标识符:


 $ docker container ls --all CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e94667fe60d2 ubuntu16_armhf_opencv "/bin/bash" 6 seconds ago Exited (0) 5 seconds ago clever_yalow 

并复制已安装OpenCV的安装目录:


 docker cp e94667fe60d2:/opencv/build/install/ ./ mv install ocv_install 

摆桌子


ocv_install复制到Raspberry Pi,设置路径并尝试从python运行OpenCV。


 export LD_LIBRARY_PATH=/path/to/ocv_install/lib/:$LD_LIBRARY_PATH export PYTHONPATH=/path/to/ocv_install/python/:$PYTHONPATH 

使用来自https://github.com/chuanqi305/MobileNet-SSD的MobileNet-SSD神经网络运行检测示例:


 import cv2 as cv print cv.__file__ classes = ['backgroud', 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor'] cap = cv.VideoCapture(0) net = cv.dnn.readNet('MobileNetSSD_deploy.caffemodel', 'MobileNetSSD_deploy.prototxt') cv.namedWindow('Object detection', cv.WINDOW_NORMAL) while cv.waitKey(1) != 27: hasFrame, frame = cap.read() if not hasFrame: break frame_height, frame_width = frame.shape[0], frame.shape[1] blob = cv.dnn.blobFromImage(frame, scalefactor=0.007843, size=(300, 300), mean=(127.5, 127.5, 127.5)) net.setInput(blob) out = net.forward() for detection in out.reshape(-1, 7): classId = int(detection[1]) confidence = float(detection[2]) xmin = int(detection[3] * frame_width) ymin = int(detection[4] * frame_height) xmax = int(detection[5] * frame_width) ymax = int(detection[6] * frame_height) if confidence > 0.5: cv.rectangle(frame, (xmin, ymin), (xmax, ymax), color=(255, 0, 255), thickness=3) label = '%s: %.2f' % (classes[classId], confidence) labelSize, baseLine = cv.getTextSize(label, cv.FONT_HERSHEY_SIMPLEX, 0.5, 1) ymin = max(ymin, labelSize[1]) cv.rectangle(frame, (xmin, ymin - labelSize[1]), (xmin + labelSize[0], ymin + baseLine), (255, 0, 255), cv.FILLED) cv.putText(frame, label, (xmin, ymin), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0)) cv.imshow('Object detection', frame) 


如此一来,一次完整的组装就不会超过20分钟。 我将Dockerfile的最终版本Dockerfile下面,并借此机会,我建议对曾经使用该库的人进行OpenCV团队的简短调查: https : //opencv.org/survey-2018.html


是的,恭喜您使用OpenCV 4! 这不仅是一个单独团队的工作,而且是整个社区的工作-OpenCV 4您。


 FROM ubuntu:16.04 USER root RUN dpkg --add-architecture armhf RUN sed -i -E 's|^deb ([^ ]+) (.*)$|deb [arch=amd64] \1 \2\ndeb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ \2|' /etc/apt/sources.list RUN apt-get update && \ apt-get install -y --no-install-recommends \ cmake \ pkg-config \ crossbuild-essential-armhf \ git \ python-pip \ libgtk2.0-dev:armhf \ libpython-dev:armhf \ libgstreamer1.0-dev:armhf \ libgstreamer-plugins-base1.0-dev:armhf \ libgstreamer-plugins-good1.0-dev:armhf \ libgstreamer-plugins-bad1.0-dev:armhf RUN pip install numpy==1.12.1 RUN git clone https://github.com/opencv/opencv --depth 1 RUN mkdir opencv/build && cd opencv/build && \ export PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig && \ cmake -DCMAKE_BUILD_TYPE=Release \ -DOPENCV_CONFIG_INSTALL_PATH="cmake" \ -DCMAKE_TOOLCHAIN_FILE="../opencv/platforms/linux/arm-gnueabi.toolchain.cmake" \ -DWITH_IPP=OFF \ -DBUILD_TESTS=OFF \ -DBUILD_PERF_TESTS=OFF \ -DOPENCV_ENABLE_PKG_CONFIG=ON \ -DPYTHON2_INCLUDE_PATH="/usr/include/python2.7" \ -DPYTHON2_NUMPY_INCLUDE_DIRS="/usr/local/lib/python2.7/dist-packages/numpy/core/include" \ -DENABLE_NEON=ON \ -DCPU_BASELINE="NEON" .. && make -j4 && make install 

Source: https://habr.com/ru/post/zh-CN430906/


All Articles