LoginSignup
2
5

More than 3 years have passed since last update.

Raspberry Pi で .NET Core + OpenCV を始める

Posted at

はじめに

.NET Coreがクロスプラットフォーム対応になって、
LinuxだろうがMacだろうが、x86だろうがarmhfだろうが、
動くようになったこのご時世だというのに、全然試していなかったので試しました。

.NET Core の導入

まずは .NET Core の導入です。
ARMでは ARM32 と ARM64 のバージョンがあるので、ターゲットに合わせて選びます。

今回はTinkerBoardというRaspberry Pi みたいな armhf (armv7l)なシングルボードコンピュータに導入しようと思いますので、
SDK 3.1.402」の「ARM32」を選びました。

OpenCV 4.4.0 の導入

OpenCV 4.4.0のリリースノート

関係ないですが、OpenCV 4.4.0 では晴れて自由に使えるようになった SIFT特徴量 がメインのモジュールに含まれるようになりました。(opencv_features2dに入ってます。)

※今回はソースコードからビルドしてみますが、他のバージョンで良ければいろんなところで配布されているのでそれを使用した方が早いです。

OpenCV 4.4.0 自体のビルド

いつもと同じように、CMakeを使って構成、Makeでビルド/インストールします。

OpenCV本体のダウンロード

mkdir src
cd src
wget https://github.com/opencv/opencv/archive/4.4.0.zip
unzip 4.4.0.zip
rm 4.4.0.zip

OpenCV contribのダウンロード

wget https://github.com/opencv/opencv_contrib/archive/4.4.0.zip
unzip 4.4.0.zip
rm 4.4.0.zip

ダウンロードし展開すると、このように opencv-4.4.0opencv_contrib-4.4.0 フォルダができあがります。(両方 4.4.0.zip というzipファイルなのでダウンロード時に上書きしないように注意。)

~/src$ ls
4.4.0.zip  opencv-4.4.0  opencv_contrib-4.4.0

そしてCMakeを使ってビルドする準備をします。

cd opencv-4.4.0
mkdir build
cd build
cmake -DOPENCV_EXTRA_MODULES_PATH=/home/XXX/src/opencv_contrib-4.4.0/modules -D WITH_LIBV4L=ON -D CMAKE_BUILD_TYPE=RELEASE -D WITH_TBB=ON -D ENABLE_NEON=ON ..

-DOPENCV_EXTRA_MODULES_PATH は 先程の opencv_contrib-4.4.0 フォルダ配下の modules を指定します。(オプションは一例です。この例ではあんまり真面目に考えてませんが、Python用のモジュールをビルドしないなど最適化する余地はあります。)

次に、ビルド/インストールをします。

make
sudo make install
sudo ldconfig

さすがに実機でやると時間がめっちゃかかるので screen コマンドで裏で走らせつつ寝ました。

OpenCvSharpのビルド

さて、ここまでで opencv の導入はできたので、それを .NET Core から使うべくOpenCVをC#ラッパーである OpenCvSharp を導入していきます。

shimat/opencvsharp: OpenCV wrapper for .NET

OpenCvSharpには OpenCV を軽くラップした薄いラッパーが同梱している(OpenCvSharp4.runtime.win とかが多分それ。)のですが、Ubuntu用は x64用しか無いのでARM版を手動でビルドしていきます。

ビルド手順はまんまこれ → Build on ARM · Issue #388 · shimat/opencvsharp

#download OpenCvSharp
cd ~/src
git clone https://github.com/shimat/opencvsharp.git

#install the Extern lib.
cd opencvsharp/src
sed -i.bak '5i\
include_directories("/usr/local/include/")\
set (CMAKE_CXX_STANDARD 11)\
' CMakeLists.txt
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig

sudo ldconfig までやると NuGet で OpenCvSharp落としてくるだけで使えるようになる。めっちゃすごい。

クロスプラットフォームサンプル

というわけで、上記手順に従うと .NET Core + OpenCV をやる最低限の準備は整うことがわかりました。ただ、やっぱりサンプルがないと寂しいので書いてみました。
一応 Windows 10 on ThinkPad X220 (x64) と Debian 9 on TinkerBoard (armv7l) で動作確認を取ったサンプルです。

このサンプルはカレントディレクトリの example.jpg というファイルを読み込んでキャニーのエッジ抽出をして結果を example_canny.jpg として保存するものです。

static void Main(string[] args) {
    using var src = new Mat("example.jpg", ImreadModes.Grayscale);
    using var dst = new Mat();

    Cv2.Canny(src, dst, 50, 200);
    Cv2.ImWrite("example_canny.jpg", dst);
    Console.WriteLine("Example done!");
}

サンプルのキモ

極力共通のコマンドを叩くと環境が揃ってビルドできるようになるようにしたかったので csproj ファイルの中でプラットフォーム依存の部分を記述しています。

  <ItemGroup Condition="$(OS.StartsWith('Windows'))">
    <PackageReference Include="OpenCVSharp4.Windows" Version="4.4.0.20200915" />
  </ItemGroup>

といってもこれだけですが。

ここでやっているのは、Windowsでビルドしたときは OpenCvSharp の「All-in-one package」への参照をもたせて先程のようなOpenCVをWindowsでビルドする必要をなくする処理です。先程紹介したOpenCVのビルド手順をなぞればここの記述は必要ありませんが、正直気力が足りないのと素直にビルド済みの配布物を使用するほうが後々トラブルが少ないという考えからです。

TinkerBoardでビルドしてみる

先程のリポジトリをTinkerBoardにクローンしてビルドしてみます。

yoh@tinkerboard:~/dev$ git clone https://github.com/yoh1496/dotnetcore-opencvsharp
Cloning into 'dotnetcore-opencvsharp'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 12 (delta 1), reused 11 (delta 0), pack-reused 0
Unpacking objects: 100% (12/12), done.
yoh@tinkerboard:~/dev$ cd dotnetcore-opencvsharp/
yoh@tinkerboard:~/dev/dotnetcore-opencvsharp$ dotnet build .
Microsoft (R) Build Engine version 16.7.0+7fb82e5b2 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  Restored /home/yoh/dev/dotnetcore-opencvsharp/dotnetcore-opencvsharp.csproj (in 960 ms).
  dotnetcore-opencvsharp -> /home/yoh/dev/dotnetcore-opencvsharp/bin/Debug/netcoreapp3.1/dotnetcore-opencvsharp.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:08.28

ビルドできますね。最高。

ここで、入力画像を dotnetcore-opencvsharp フォルダ直下に配置します。scp で渡しました。
画像は何でもいいので適当に旅行で撮った写真を使ってみました。(掲載に当たり縮小してます)

a.jpg

yoh@tinkerboard:~/dev/dotnetcore-opencvsharp$ ls
Program.cs  bin  dotnetcore-opencvsharp.csproj  example.jpg  obj

では実行!

yoh@tinkerboard:~/dev/dotnetcore-opencvsharp$ dotnet run .
Example done!
yoh@tinkerboard:~/dev/dotnetcore-opencvsharp$ ls
Program.cs  bin  dotnetcore-opencvsharp.csproj  example.jpg  example_canny.jpg  obj

example_canny.jpg が出力されてる!
出力結果を確認してみます。 scp で取ってきてもいいんですが、面倒くさかったので Visual Studio Code の Remote-SSH 拡張機能で開きました。

image.png

ちゃんとエッジ抽出できてる!

Windows で実行してみる

image.png

できました!

SSH-Remote で armhf の Linux につなぐとデバッガが使用できないんですが、Windows環境だとちゃんと使用できて便利です。開発はWindowsでやって、実際に動かすのはARMみたいな使い分けをしていこうかなと思います。

ARM でのみ発生する問題もあると思うので、そういった場合はリモートデバッグを使うとよいかもしれません。まだ試せてませんが、、、

Remote Debugging On Linux Arm · OmniSharp/omnisharp-vscode Wiki

終わりに

Windowsで書いたコードがそのまま Linux on ARM でも動作するのは便利ですね。試してませんがまぁMacでも動くんでしょう。
.NET Coreが動くのが便利なのもそうなんですが、vscodeがARMのLinuxマシン上でも問題なく繋げるのが最高に便利ですね。

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5