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例外が発生する場合があります。対策等はこちらの記事を参照してください。
このページのキーワード
  • C#
  • OpenCV
  • OpenCVSharp
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2014-04-08
iPentec all rights reserverd.