OpenCVSharp を用いて C#でOpenCV を利用する - C#
OpenCVSharpを用いてC#でOpenCVを利用する手順を紹介します。
準備
OpenCVのダウンロードとインストール
OpenCVをダウンロードしてインストールします。手順は
こちらの記事を参照してください。
OpenCVSharpのダウンロード
OpenCVSharpをダウンロードします。
こちらのサイトからダウンロードできます。NuGetまたはZipファイルでのダウンロードができます。Zipファイルでダウンロードした際にはファイルを展開しておきます。
アプリケーションの作成
Windowsフォームアプリケーションプロジェクトを新規作成します。
参照設定の追加
ソリューションエクスプローラの[参照設定]ノードを選択し右クリックします。ポップアップメニューが表示されますので[参照の追加]メニューを選択します。
参照マネージャダイアログが表示されます。ダイアログ下部の[参照]ボタンをクリックします。
[参照するファイルの選択]ダイアログボックスが開きます。OpenCVSharpのアセンブリ(OpenCvSharp.dll)を選択します。OpenCvSharpは今回は32ビット版(x86)を用いました。
アセンブリが一覧に表示され、左端のチェックボックスにチェックがつきます。[OK]ボタンをクリックし、参照を追加します。
[参照設定]ノードに"OpenCvSharp"が追加されました。
OpenCV DLLの追加
OpenCVをインストールしたディレクトリの中にある、DLLをプロジェクトに追加します。
今回は
(OpenCVのインストールディレクトリ)\build\x86\vc12\bin
ディレクトリにあるDLL一式をプロジェクトに追加しました。プロジェクトへの追加は、エクスプローラでDLLファイルを選択し、ソリューションエクスプローラのプロジェクトノードへドラッグ&ドロップすることで追加できます。
UI
下図のUIを作成します。フォームにButtonを1つ配置します。
コード
以下のコードを記述します。コード自体はOpenCvSharpのサンプルコードと同じものです。画像ファイル(yalta.jpg)と顔認識用のパターンファイル(haarcascade_frontalface_default.xml)はOpenCvSharpのサンプルからコピーしてプロジェクトの内に配置します。また、このとき、DLLやサンプル画像が出力ディレクトリにコピーされることを確認します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;
namespace SimpleOpenCV
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
CvColor[] colors = new CvColor[]{
new CvColor(0,0,255),
new CvColor(0,128,255),
new CvColor(0,255,255),
new CvColor(0,255,0),
new CvColor(255,128,0),
new CvColor(255,255,0),
new CvColor(255,0,0),
new CvColor(255,0,255),
};
const double Scale = 1.14;
const double ScaleFactor = 1.0850;
const int MinNeighbors = 2;
using (IplImage img = new IplImage("yalta.jpg", LoadMode.Color))
using (IplImage smallImg = new IplImage(new CvSize(Cv.Round(img.Width / Scale), Cv.Round(img.Height / Scale)), BitDepth.U8, 1)) {
// 顔検出用の画像の生成
using (IplImage gray = new IplImage(img.Size, BitDepth.U8, 1)) {
Cv.CvtColor(img, gray, ColorConversion.BgrToGray);
Cv.Resize(gray, smallImg, Interpolation.Linear);
Cv.EqualizeHist(smallImg, smallImg);
}
//using (CvHaarClassifierCascade cascade = Cv.Load<CvHaarClassifierCascade>(Const.XmlHaarcascade)) // どっちでも可
using (CvHaarClassifierCascade cascade = CvHaarClassifierCascade.FromFile("haarcascade_frontalface_default.xml")) //
using (CvMemStorage storage = new CvMemStorage()) {
storage.Clear();
// 顔の検出
Stopwatch watch = Stopwatch.StartNew();
CvSeq<CvAvgComp> faces = Cv.HaarDetectObjects(smallImg, cascade, storage, ScaleFactor, MinNeighbors, 0, new CvSize(30, 30));
watch.Stop();
Console.WriteLine("detection time = {0}ms\n", watch.ElapsedMilliseconds);
// 検出した箇所にまるをつける
for (int i = 0; i < faces.Total; i++) {
CvRect r = faces[i].Value.Rect;
CvPoint center = new CvPoint
{
X = Cv.Round((r.X + r.Width * 0.5) * Scale),
Y = Cv.Round((r.Y + r.Height * 0.5) * Scale)
};
int radius = Cv.Round((r.Width + r.Height) * 0.25 * Scale);
img.Circle(center, radius, colors[i % 8], 3, LineType.AntiAlias, 0);
}
}
CvWindow.ShowImages(img);
}
}
}
}
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
ボタンをクリックするとウィンドウが表示され、画像認識結果が表示されます。画像で顔として認識された部分に○が表示されています。
補足:実行時にTypeInitializationException が発生する場合
実行時にTypeInitializationException例外 が発生することがあります。主な原因は2つあります。
1:OpenCVのDLLファイルが実行ファイルのあるディレクトリにコピーされない
OpenCVのDLLファイルが実行ファイルのディレクトリにコピーされないため、TypeInitializationException例外 が発生する場合があります。この場合は、ソリューションエクスプローラでOpenCVのDLLを選択し、"出力ディレクトリにコピー"プロパティを"常にコピーする"か"新しい場合にコピーする"に変更します。
2:デフォルトのプロジェクト設定で64ビット版のOpenCVのDLLを利用している
64ビット版のOpenCVのDLLを利用しているとTypeInitializationException例外が発生する場合があります。対策等は
こちらの記事を参照してください。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用