この数週間は私たちのチームにとって困難でした。 OpenCV 4がリリースされ 、それと共に、OpenCVを含むIntelのOpenVINOツールキット R4 の準備をしていました。 しばらく気が散って、いつものように、OpenCVフォーラムとユーザーのコメントについて見ていきます。ここでは、OpenCVはIoTではなく、Raspberry Piの下では組み立てるのに十分である-十分なはんだがありません。運がよければ午前中に準備が整います。
したがって、手をつないで、優れたCPUアーキテクチャによって駆動される64ビットOSのマシンのリソースを使用して、ARMプロセッサで実行される32ビットオペレーティングシステム用のOpenCVライブラリをアセンブルする方法を提案します。 魔術 クロスコンパイル、そうでなければ!
問題の声明
一般的にネイティブと呼ばれるボード上で直接コンパイルするのは本当に骨が折れるため、ここでは、より強力なコンピューティングデバイス(ホストと呼びましょう)が小さな親類のためにバイナリを準備できるプロジェクトを構築する方法を検討します。 さらに、両方のマシンで異なるCPUアーキテクチャを使用できます。 これはクロスコンパイルです。
したがって、OpenCVを詰めたラズベリーパイを準備するには、次のものが必要です。
- Ubuntu 16.04イメージドッカーカーカス
- ホストマシンは、Raspberry Piよりも強力です(そうでなければ、何がポイントなのでしょうか?)
- ARMhfのクロスコンパイラ、および対応するアーキテクチャのライブラリ
OpenCVを構築するプロセス全体がホストマシンで実行されます。 自宅でUbuntuを使用しています。 Linuxの別のバージョンでは、再生の問題は発生しません。 Windowsユーザーの場合-私は、あきらめずに自分自身で解決しようと心から願っています。
Dockerをインストールする
約1週間前にdockerと知り合いになったので、おいしい塩と構文糖を味に加えます。 Dockerfile、イメージとコンテナーの概念-3つの成分で十分です。
Docker自体は、必要なコンポーネントセットを備えたオペレーティングシステムの構成を作成および再現するためのツールです。 Dockerfileは、通常ホストマシンで使用するシェルコマンドのセットですが、この場合、それらはすべていわゆるdocker
イメージに適用されます。
Dockerをインストールするには、最も簡単な方法を検討してください。apt apt-get
配信サービスでパッケージを注文します。
sudo apt-get install -y docker.io
dockerデーモンに要求するすべてを提供し、システムからログアウトします(それに応じてログインに注意してください)。
sudo usermod -a -G docker $USER
ワークスペースを準備する
最も一般的な準備のRaspberry Pi(私の場合はRPI 2モデルB)は、Raspbian(Debianベース)オペレーティングシステムを搭載したARMv7 CPUです。 Ubuntu 16.04に基づいてdocker
イメージを作成します。このイメージでは、クロスコンパイラ、軍隊ライブラリを報告し、同じ場所でOpenCVを収集します。
Dockerfile
するパパを作成します。
mkdir ubuntu16_armhf_opencv && cd ubuntu16_armhf_opencv touch Dockerfile
apt-get
パッケージインストーラーのベースOSおよび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
ファイルを見ると、そのようなエラーはそれぞれ、たとえば次のような行に対応しています。
エラー
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
解決策 :
2つに分けます:
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
したがって、いくつかのパッケージソースを置き換える必要があります。 ドッカーでは、すべてを1つのコマンドで置き換えます。
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
はエラーなしで機能apt-get update
はずです。
必要なパッケージを入れます
git
、 python-pip
、 cmake
、 pkg-config
などのホストパッケージと、gcc / g ++クロスコンパイラのセットであるcrossbuild-essential-armhf
( arm-linux-gnueabihf-gcc
およびarm-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=OFF
、BUILD_PERF_TESTS=OFF
、テストビルドを無効にします。
OPENCV_ENABLE_PKG_CONFIG=ON
-pkg-configがGTKなどの依存関係を見つけることができるようにします。PKG_CONFIG_PATH
は、pkg-config
がライブラリを探す正しいパスです。
PYTHON2_INCLUDE_PATH
、PYTHON2_NUMPY_INCLUDE_DIRS
-python2のラッパーのクロスコンパイルに必要なパス。
ENABLE_NEON=ON
、CPU_BASELINE="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
make
を呼び出し、 make 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