OpenCvSharp を Linux で動かす完全ガイド【C#/.NET 8】

OpenCV for C#
📌 準備: OpenCV の環境構築がまだの方はこちら → C++ 環境構築ガイド / C#(OpenCvSharp)セットアップ

OpenCvSharp を Linux で動かす完全ガイド【C#/.NET 8】

Windows で OpenCvSharp を使っている開発者が Linux 環境(サーバー・コンテナ・CI)に移植しようとすると、runtime パッケージの選択で詰まるケースが多くあります。この記事では Ubuntu 上で OpenCvSharp を使った C# プログラムをビルド・実行できる状態 にする手順を解説します。


前提環境

項目 バージョン・補足
OS Ubuntu 22.04 LTS / 24.04 LTS
.NET .NET 8(現行 LTS)
OpenCvSharp OpenCvSharp4 4.9.x(NuGet)
runtime パッケージ OpenCvSharp4.runtime.ubuntu.22.04-x64(NuGet)

Windows との違い: Windows では OpenCvSharp4.runtime.win を使いますが、Linux では OS ディストリビューション別の runtime パッケージが必要です。これが最初のつまずき点です。


手順

1. .NET 8 SDK のインストール

sudo apt update
sudo apt install -y dotnet-sdk-8.0
dotnet --version

8.x.x が表示されれば OK です。

2. プロジェクト作成

mkdir opencv-linux-sample && cd opencv-linux-sample
dotnet new console -n OpenCvLinuxSample
cd OpenCvLinuxSample

3. NuGet パッケージの追加

Linux 向けの runtime パッケージは ディストリビューション・アーキテクチャ別 に提供されています。Ubuntu 22.04 / 24.04 の x64 環境であれば以下を使います。

dotnet add package OpenCvSharp4
dotnet add package OpenCvSharp4.runtime.ubuntu.22.04-x64

⚠️ Ubuntu 20.04 の場合は OpenCvSharp4.runtime.ubuntu.20.04-x64 を、ARM64(例: Raspberry Pi / Apple Silicon の Linux VM)の場合は対応するパッケージを NuGet で検索してください。パッケージ名に OS バージョンとアーキテクチャが含まれているので、自分の環境に合ったものを選びます。

追加後、OpenCvLinuxSample.csproj を確認します。

cat OpenCvLinuxSample.csproj

以下のように両パッケージが含まれていれば OK です。

<PackageReference Include="OpenCvSharp4" Version="4.9.*" />
<PackageReference Include="OpenCvSharp4.runtime.ubuntu.22.04-x64" Version="4.9.*" />

4. ネイティブライブラリの配置確認

dotnet build を実行すると、runtime パッケージに同梱されている libOpenCvSharpExtern.so が出力ディレクトリにコピーされます。

dotnet build
ls bin/Debug/net8.0/libOpenCvSharpExtern.so

ファイルが存在することを確認してください。これが見当たらない場合はネイティブライブラリが読み込まれず、実行時に DllNotFoundException が発生します。

5. サンプル画像の用意

動作確認用に小さな PNG 画像を用意します。任意の画像を sample.png として配置してください。コマンドで生成する場合は以下が手軽です。

# ImageMagick がある場合
convert -size 640x480 xc:gray sample.png

# convert がない場合は scp 等で転送する

動作確認

以下の完全プログラムで、画像の読み込み・グレースケール変換・リサイズ・書き出しが正常に動くか確認します。

using OpenCvSharp;

// --- 動作確認: 画像読み込み・変換・書き出し ---
const string inputPath  = "sample.png";
const string outputPath = "output_gray.png";

// 画像読み込み
using var src = Cv2.ImRead(inputPath, ImreadModes.Color);
if (src.Empty())
{
    Console.Error.WriteLine($"画像を読み込めませんでした: {inputPath}");
    return 1;
}
Console.WriteLine($"読み込み成功: {src.Width}x{src.Height}, チャンネル数={src.Channels()}");

// グレースケール変換
using var gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);

// 半分のサイズにリサイズ
using var resized = new Mat();
Cv2.Resize(gray, resized, new Size(src.Width / 2, src.Height / 2));

// 書き出し
bool saved = Cv2.ImWrite(outputPath, resized);
Console.WriteLine(saved ? $"保存成功: {outputPath}" : "保存失敗");

return 0;

実行します。

dotnet run

実行すると以下のように表示されます。

読み込み成功: 640x480, チャンネル数=3
保存成功: output_gray.png

output_gray.png が生成されていれば Linux 上での OpenCvSharp の動作確認は完了です。

Docker コンテナで動かす場合

CI やコンテナ環境でも同じ手順が使えます。Dockerfile の最小構成例を示します。

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
COPY . .
RUN dotnet publish -c Release -o /out

FROM mcr.microsoft.com/dotnet/runtime:8.0
WORKDIR /app

# OpenCvSharp が依存する共有ライブラリをインストール
RUN apt-get update && apt-get install -y \
    libgomp1 \
    && rm -rf /var/lib/apt/lists/*

COPY --from=build /out .
COPY sample.png .
ENTRYPOINT ["dotnet", "OpenCvLinuxSample.dll"]

libgomp1(OpenMP ランタイム)は OpenCV のネイティブライブラリが依存するため、runtime ベースイメージには別途インストールが必要です。これも見落としやすい点です。


つまずきポイント

⚠️ DllNotFoundException: libOpenCvSharpExtern.so

症状: 実行時に System.DllNotFoundException: Unable to load shared library 'OpenCvSharpExtern' が出る。

原因と対処:

  1. runtime パッケージが入っていない
    OpenCvSharp4.runtime.ubuntu.22.04-x64(環境に合ったもの)を追加していない。dotnet add package で追加後、dotnet build を再実行してください。

  2. OS バージョンとパッケージが一致していない
    Ubuntu 24.04 に runtime.ubuntu.20.04-x64 を入れても動く場合とそうでない場合があります。まず 22.04 向けを試し、それでも解決しない場合は ldd でライブラリの依存を確認します。

ldd bin/Debug/net8.0/libOpenCvSharpExtern.so
  1. LD_LIBRARY_PATH の問題
    dotnet run ではなく自前でバイナリを配置して実行している場合、libOpenCvSharpExtern.so と同じディレクトリにいないと読み込めないことがあります。実行ディレクトリを bin/Debug/net8.0/ に合わせるか、LD_LIBRARY_PATH を設定してください。

⚠️ Mat の Dispose 漏れによるメモリリーク

Linux 環境はサーバー・長時間稼働のユースケースが多く、Mat の Dispose 漏れが致命的です。new Mat() を使う場合は必ず using で囲んでください。

// NG: Dispose が呼ばれない
var gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);

// OK: using で確実に解放
using var gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);

ネイティブメモリは GC の管理外のため、using を省略するとプロセスのメモリ使用量が増え続けます。

⚠️ GUI 表示(Cv2.ImShow)はサーバー Linux では動かない

Cv2.ImShow はディスプレイ(X11 / Wayland)が必要です。ヘッドレスサーバーや Docker コンテナでは呼ばない設計にしてください。処理結果の確認は Cv2.ImWrite でファイルに書き出すか、Cv2.ImEncode でメモリ上にエンコードして使います。


まとめ

  • Linux で OpenCvSharp を動かすには OpenCvSharp4 に加え OpenCvSharp4.runtime.ubuntu.xx.xx-x64 を追加する
  • dotnet build 後に libOpenCvSharpExtern.so が出力ディレクトリにあることを確認する
  • Docker コンテナでは libgomp1 等の依存ライブラリを apt-get で別途インストールする
  • ヘッドレス環境では Cv2.ImShow を使わず Cv2.ImWrite / Cv2.ImEncode で結果を取り出す
  • Mat は必ず using で解放する(長時間稼働するサーバーほど重要)

Linux 上で画像処理が動き始めると、差分検出や動体検知など本格的な処理も実装できます。差分処理の実装については Cv2.Absdiff の使い方【OpenCV/C#(OpenCvSharp)】〜差分画像を作る〜 も参考にしてください。カメラ入力を扱う場合は VideoCapture の使い方【OpenCV/C#(OpenCvSharp)】〜カメラ映像を取り込む〜 が参考になります。

🛠 画像処理のプロが開発するSDK/API

本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/APIを開発しています。SDK は C#/.NET 8 に正式対応しており、OpenCvSharp を使うプロジェクトからそのまま組み込めます。

→ 顔認証のなりすまし対策 設計チェックリスト(当ブログ)
→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

タイトルとURLをコピーしました