
みなさんこんにちは、ガノー(Ganohr)です。
今回は『OpenCV』と『Visual Studio Community』(2017)を用いて、‘C#’で簡単に使えるフレームワークである『OpenCvSharp』(開発者:Schima氏、ブログ、リポジトリ)を導入し、‘Hello World’的な確認コードを実際に作成して試す手順を解説します。
OpenCvSharpは『NuGet』に対応しているので導入は簡単なのですが、公式サイトで公開されているテスト用のコードが最新版では動かなかったり、パッケージ導入などで調査が必要でしたので、本記事で解説します。
OpenCvSharp関連リンク集
- OpenCV
- OpenCV - Wikipedia
- OpenCV-CookBook(日本語)
- C# - Wikipedia
- Visual Studio Community - Microsoft
- Visual Studio Communityのダウンロード
- NuGet - Wikipedia
- MicrosoftによるNuGetの解説
- 開発者Schima氏のブログ
- OpenCVSharpのリポジトリ
- メインサイトOpenCvSharpのサンプル・ダウンロード
更新履歴
2020/08/06
・ダウンロードマネージャーを変更
・ダウンロードリストを再構築
2020/05/20
・ OpenCvSharpV2に「古い(非推奨)」を明示
・ V4に「推奨」を明示
・ V4の2つのサンプルに解説を追記
2020/05/15
・ シンタックスハイライトの改修
・ その他軽微な修正
2019/09/21 微修正
2019/07/03 カテゴリを調整
2019/07/01 リンク集を更新
2019/06/26 誤変換の修正、わかりにくい表現を修正
コントロールとして表示する方法の解説を追加
2019/06/25 サンプルコードをダウンロード可能に
2019/06/24 C#ライクな記述を追加公開
2019/06/23 公開
目次
- 1.簡単な用語解説
- 1.1.OpenCVとはなにか
- 1.2.NuGetとはなにか
- 1.3.OpenCvSharpとはなにか
- 2.NuGetを用いたOpenCvSharpの導入とサンプルコード / Hello World
- 2.1.各種サンプルコードのダウンロード
- 2.2.OpenCvSharp Ver2.4(古い / 非推奨)
- 2.2.1.新規プロジェクトの作成
- 2.2.2.NuGetでOpenCvSharpのパッケージを導入する
- 2.2.3.Hello Worldの作成
- 2.2.4.実行結果
- 2.3.OpenCvSharp 4(参考/推奨)
- 2.3.1.新規プロジェクトの作成
- 2.3.2.NuGetでOpenCvSharp4.Windowsのパッケージを導入する
- 2.3.3.Hello Worldの作成
- 2.3.4.実行結果
- 3.OpenCvSharp2と、OpenCvSharp3&OpenCvSharp4の違い
- 4.OpenCvSharp 4でのC#ライクなコーディング(推奨)
- 4.1.コード
- 4.2.解説
- 4.3.フォームコントロール
- 5.最後に
簡単な用語解説
OpenCVとはなにか
‘OpenCV’は、画像処理用のマルチプラットフォーム(※1)なフレームワーク(※2)です。
対応するプログラミング言語はメインはC言語、C++言語ですが、有志によりラッパーフレームワーク(※3)が多数開発されています。
そのため、数多くのプログラミング言語から使用可能です。
- ※1 マルチプラットフォーム=複数のOSで使用可能という意味
- ※2 フレームワーク=土台という意味。画像処理用の土台を提供している。
- ※3 ラッパーフレームワーク=別の言語から使用できるようにしたフレームワーク。今回ならOpenCvSharpが該当する。


NuGetとはなにか
‘NuGet’は、.Net Frameworkに対応したパッケージマネージャー(※1)です。
NuGetは最近のVisual Studio(2012以降)には標準で搭載されており、インターネットに接続可能であれば簡単に使用できます。
NuGetを用いない場合、パッケージの導入には煩雑な作業(※2)が必要になります。
NuGetを用いれば、大抵の場合ワンクリックだけで導入できます。
今回使用するOpenCvSharpはこのNuGetに対応しているため、導入自体は簡単です。
- ※1 パッケージマネージャー=パッケージ(必要な機能がまとめられたもの)を管理するソフト
- ※2 煩雑な導入作業:NuGetを用いない場合、例えばdllファイルのコピーや参照の追加などが必要です。

OpenCvSharpとはなにか
‘OpenCvSharp’は、日本人開発者であるSchima氏(ブログ)による、OpenCVのC#用ラッパーフレームワークです。
OpenCVに習ったコーディングとともに、C#らしいコーディングが可能になったフレームワークです。
例えば、C言語やC++をターゲットにしたフレームワークは、往々にしてメモリ管理が煩雑な場合が多いのですが、
OpenCvSharpであればIDisposable
が適宜に実装されているため、using { }
ステートメントによる自動解放の恩恵を受けられます。
また、OpenCVの内部画素表現を、.Net FrameworkのBitmap
型へ変換するための実装が含まれるなど、実用性に配慮されている点も特徴といえます。
その他、NuGetパッケージも2019年4月時点でも更新がかかっているなど、他のOpenCV系ラッパーフレームワークと比べて開発が続いている点も特筆すべきでしょう。
ただし、OpenCvSharpはOpenCVのAPIに準じた実装のために、OpenCvSharp Ver 2.4.xと、それ以外のバージョンで大幅に実装が異なっている点は留意せねばなりません。
これはOpenCV自体の変遷なのでどうしようもないのですが、公式サイトでのサンプルコードを実行する際にも留意が必要です。

NuGetを用いたOpenCvSharpの導入とサンプルコード / Hello World
OpenCvSharpを導入するには、NuGetを用いれば簡単です。
ただし、NuGet上に現在公開されているOpenCvSharpには複数のバージョンや複数のプラットフォームに向けた実装が公開されているため、留意が必要です。
今回は「『Windows 10』の64bit環境で動作させる」ことを前提として導入していきます。
また、OpenCvSharpのバージョンは大まかに分けて
- OpenCvSharp 2.4.x
- OpenCvSharp 3
- OpenCvSharp 4
と3つのバージョンがあります。
今回はAPI仕様が2.4.x系とそれ以外に分かれる点と、現行最新で更新が続いている4系での導入を解説し、それぞれのサンプルコード(‘Hello World’)を解説します。
各種サンプルコードのダウンロード
当記事では、解説しているコードを全てダウンロードできます。
ダウンロードの際は、以下の条件に同意してください。
- このサンプルやファイルをWEBサイト等に公開することを禁止します
- このサンプルをベースに改造・開発を行った場合、ソースコードを不特定多数に公開することを禁止します
- このサンプルをベースに改造・開発を行い、ビルドした結果については一切の制限事項はありません
なお、この制限の意図は「最近横行している、他人のWEBコンテンツを不正に流用して金儲けをおこなおうとするスプログやまとめサイトへの転載を排除するため」です。
良識的な利用においては、一切の制限を課す予定はありません。
ご理解の上、ダウンロードをお願いします。
※ ダウンロードしたコードにはコメントが付与されておりません。
※ なお、ダウンロードしたコードで分からない点がありましたら、当記事にコメントを頂ければフォローアップいたします。
OpenCvSharp Ver2.4(古い / 非推奨)
(2020/05/20 追記)このバージョンは非常に古く、通常は次節にて解説している「Ver4系」をご使用ください。Ver2系からVer4系への変更は現実的ではありません。(追記以上)
ここでは、以下の手順を行います。
- Visual Studioで新規プロジェクトとして「HelloOpenCvSharpV2」を作成する
- NuGetでOpenCvSharp ver 2.4系のパッケージを導入する
- Hello Worldを作成し実行する
実際のサンプルコードもダウンロードできます。
(実際に動作させて確認するには、Visual Studioでのビルドが必要です)
新規プロジェクトの作成
新規プロジェクトから、
「Windows フォームアプリケーション」を選択し、「HelloOpenCvSharpV2」という名前でプロジェクトを作成します。
自動生成される「Form1.cs」は不要なので、削除します。
また、それに伴い、コード内の不必要な定義も削除します。





NuGetでOpenCvSharpのパッケージを導入する
NuGetでパッケージを導入します。
様々なパッケージがありますが、インストールするのは「OpenCvSharp-AnyCPU v2.4.xxxx」のみです。
それ以外は必要ありません。
まず、「プロジェクト(P)」⇒「NuGetパッケージの管理」を選択します。
続けて、「参照」タブを選択し、「opencvsharp」と入力してパッケージを探します。
「OpenCvSharp-AnyCPU」をクリックすると「インストール」というボタンが出てくるので、それを押せばインストールされます。



Hello Worldの作成
後は、以下に示すサンプルのHello World(ハローワールド)のコードを、実際に入力します。
using System;
using OpenCvSharp;
namespace HelloOpenCVSharpV2
{
static class Program
{
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main()
{
// 生成する画像と画面の大きさを定義
var w = 1024;
var h = 768;
// 画像を記憶する変数を定義(IplImageが使えるのはVer2まで)
IplImage img = Cv.CreateImage(new CvSize(w, h), BitDepth.U8, 3);
// 画像内の全ピクセル分繰り返す
for (int y = 0; y < img.Height; y++)
{
for (int x = 0; x < img.Width; x++)
{
// Cv.Set2Dで画像の任意の位置(y, x)へ、特定の色を設定する
// 色はCvScalarで指定する。この関数は引数として「r,g,b」(0-255)を受け取る。
// なお255以上は255と読み替えられる(Ver2まで)。
Cv.Set2D(img, y, x, new CvScalar(x, y, x + y));
}
}
// ウィンドウのタイトル及び画像の上に書き出す文字列を定義する
var hello = "Hello OpenCVSharp";
// 画像の上の、「文字列を書き出す位置」を指定する
var pos = new CvPoint(50, 100);
// 画像の上に、「文字列を書き出すときのフォント」を指定する
var font = new CvFont(FontFace.HersheyPlain, 4.0f, 4.0f);
// 画像の上に、「文字列を書き出すときの色」を指定する
var color = new CvScalar(255, 255, 255);
// 変数「hello」で指定されたタイトルを持つフォームを作る
Cv.NamedWindow(hello);
// 画像の任意の位置へ、文字列をフォントと色を指定して書き込む
Cv.PutText(img, hello, pos, font, color);
// 作成した画像をフォームへ配置する
Cv.ShowImage(hello, img);
// フォームで何らかのキー入力がなされるまで待機する
Cv.WaitKey();
// 作成したウィンドウを破棄する
Cv.DestroyWindow(hello);
// 作成した画像を破棄する
Cv.ReleaseImage(img);
}
}
}
実行結果
実行すると以下のようなグラフィカルな画面が表示されます。

OpenCvSharp 4(参考/推奨)
(2020/05/20 追記)特段の理由がない限り、このバージョンを使用してください。なお、このサンプルは既存のOpenCVを用いた別言語からの移植を想定しています。C#で新たにOpenCVを用いたアプリケーションを作成したいと考えている方は、次節にて解説している「C#らしいコーディング例」を参考にしてください。(追記以上)
続けて、OpenCvSharp4を導入して同じ動作をするように記述します。
導入するパッケージが「OpenCvSharp4.Windows」である以外、導入手順は同じです。
新規プロジェクトの作成



NuGetでOpenCvSharp4.Windowsのパッケージを導入する

Hello Worldの作成

using System;
using OpenCvSharp;
namespace OpenCvSharpTest
{
static class Program
{
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main()
{
// 生成する画像と画面の大きさを定義
var w = 1024;
var h = 768;
// 画像を記憶する変数を定義(Ver3以降はMat型を使用)
// ※ MatType.CV_8UC3は「8ビット・アンサインド・3色」という意味
var img = new Mat(new Size(w, h), MatType.CV_8UC3);
// 画像内の全ピクセル分繰り返す
for (int y = 0; y < img.Height; y++)
{
for (int x = 0; x < img.Width; x++)
{
// img.Setで画像の任意の位置(y, x)へ、特定の色を設定する
// 色は自作関数のMyScalarで指定する
// この関数はCv.Scalar/Cv2.Scalarのバージョン差異を吸収する
img.Set(y, x, MyScalar(x, y, x + y));
}
}
// ウィンドウのタイトル及び画像の上に書き出す文字列を定義する
var hello = "Hello OpenCVSharp V4";
// 画像の上の、「文字列を書き出す位置」を指定する
var pos = new Point(50, 100);
// 画像の上に、「文字列を書き出すときのフォント」を指定する
var font = HersheyFonts.HersheyPlain;
// 画像の上に、「文字列を書き出すときの色」を指定する
var color = new Scalar(255, 255, 255);
// 変数「hello」で指定されたタイトルを持つフォームを作る
Cv2.NamedWindow(hello);
// ウィンドウの大きさを変更する
Cv2.ResizeWindow(hello, w, h);
// 画像の任意の位置へ、文字列をフォントと色を指定して書き込む
Cv2.PutText(img, hello, pos, font, 4.0f, color);
// 作成した画像をフォームへ配置する
Cv2.ImShow(hello, img);
// フォームで何らかのキー入力がなされるまで待機する
Cv2.WaitKey();
// 作成したウィンドウを破棄する
Cv2.DestroyWindow(hello);
// 作成した画像を破棄する
img.Dispose();
}
// CvScalarのバージョン差異を吸収するための関数を定義
static int MyScalar(int b, int g, int r)
{
return
(r > 255 ? 255 : r) * 256 * 256 +
(g > 255 ? 255 : g) * 256 +
(b > 255 ? 255 : b);
}
}
}
実行結果

OpenCvSharp2と、OpenCvSharp3&OpenCvSharp4の違い
OpenCvSharpはバージョン2系か、それ以上のバージョンかによって、記述が異なります。
わかりにくいのですが、2系の場合はCv
クラスを用い、3以上のバージョンではCv2
を用います。
また、IplImage
クラスが使えるのは『OpenCvSharp ver 2.4』までであり、それ以降はMat
クラスを用います。
多くのクラス名・フィールド名からも冗長なCv
の名称が消えているため、それに合わせて変更が必要です。
さらに、Scalar
(CvScalar
)も動作がバージョンで異なるため、考慮せねばなりません。


OpenCvSharp 4でのC#ライクなコーディング(推奨)
(2020/05/20 追記)特段の理由がない限り、C#で一からコーディングする際は、この内容をベースに開発を行ってください。(追記以上)
Cv2
を用いた記述はC言語やC++言語での記述を踏襲できることは強みです。
しかし、私はC#ならC#っぽい記述がしたいのと、そもそもオリジナルのアプリケーションに機能拡張を目的としてOpenCVが使用したいのです。
そのためにWindowsコントロールとして表示したり、Bitmap
オブジェクトとして表示できるようにしましょう。
- C#ライクなコーディングがしたい
- Windowsコントロールとして表示したい
Bitmap
オブジェクトとして表示したい
コード

using System;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace HelloOpenCVSharpV4_2
{
static class Program
{
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main()
{
// 生成する画像と画面の大きさを定義
var w = 1024;
var h = 768;
// 画像を記憶する変数を定義(Ver3以降はMat型を使用)し、自動解放させる
// ※ MatType.CV_8UC3は「8ビット・アンサインド・3色」という意味
using (var img = new Mat(new Size(w, h), MatType.CV_8UC3))
{
// 画像内の全ピクセル分繰り返す
for (int y = 0; y < img.Height; y++)
{
for (int x = 0; x < img.Width; x++)
{
// img.Setで画像の任意の位置(y, x)へ、特定の色を設定する
// 色は自作関数のMyScalarで指定する
// この関数はCv.Scalar/Cv2.Scalarのバージョン差異を吸収する
img.Set(y, x, MyScalar(x, y, x + y));
}
}
// ウィンドウのタイトル及び画像の上に書き出す文字列を定義する
var hello = "Hello OpenCVSharp V4";
// 画像の上の、「文字列を書き出す位置」を指定する
var pos = new Point(50, 100);
// 画像の上に、「文字列を書き出すときのフォント」を指定する
var font = HersheyFonts.HersheyPlain;
// 画像の上に、「文字列を書き出すときの色」を指定する
var color = new Scalar(255, 255, 255);
// 画像の任意の位置へ、文字列をフォントと色を指定して書き込む
img.PutText(hello, pos, font, 4.0f, color);
// フォームを作成する
// ※ 別にRADで作成してもよい
using (var form = new Form())
{
// 変数「hello」で指定されたタイトルをフォームへ設定する
form.Text = hello;
// ウィンドウの大きさを変更する
form.Size = new System.Drawing.Size(w, h);
// 作成した画像をフォームへ配置する
form.BackgroundImage = BitmapConverter.ToBitmap(img);
// 作成した画像をフォームに(伸縮許可指定で)フィットさせる
form.BackgroundImageLayout = ImageLayout.Stretch;
// 作成したフォームをアプリケーションとして作動させる(終了まで待機される)
Application.Run(form);
}
}
}
// CvScalarのバージョン差異を吸収するための関数を定義
static int MyScalar(int b, int g, int r)
{
return System.Drawing.Color.FromArgb(
r > 255 ? 255 : r,
g > 255 ? 255 : g,
b > 255 ? 255 : b).ToArgb();
}
}
}
解説
System.Drawing.Size
とOpenCvSharp.Size
で名称がバッティングしているため、明示的に指定しなければなりません。Cv.CvFont
には倍率が含まれるものの、OpenCvSharp.Font
には倍率が含まれません。Mat
のインスタンスを、BitmapConverter.ToBitmap(img);
によってBitmap
のインスタンスへコンバートできます。MyScalar
をSystem.Drawing.Color.FromArgb(…).ToArgb()
を使って記述できます。
フォームコントロール
Bitmap
型ではなく、直接コントロールとしてフォーム上に配置することも可能です。

using OpenCvSharp.Userinterface;
で参照を追加しておくusing(var pbox = new PictureBoxIpl()){ ~ }
でインスタンス作成と解放を可能にPictureBoxIpl.ImageIpl
はImageIpl
型ではなく、Mat
型のインスタンスを受け取り、表示する
最後に
OpenCvSharpはどのパッケージを導入すればよいのか初見だとわかりにくい点と、
そもそもバージョンによって色々な違いがあるためインターネット上にある情報が色々と古いという欠点があります。
しかし、一度情報を整理すれば最新のAPIも比較的容易に使えるように感じました。
今後OpenCVを使っていく上で、活用していく予定です。
この場を借りて、開発者のSchima氏にお礼を申し上げます。ありがとうございました!
今回の内容が参考になれば幸いです。
以上、ガノー(Ganohr)でした!
コメントを書く