【OpenCV/C#】Visual Studio 2017で環境構築してみた。

1. 目的

OpenCVを使用したWindowsアプリケーション開発では、これまでC++で環境構築してきたが、今回はC#で環境構築してみたので、紹介します。

残念ながらOpenCVはC#では使用できないため、OpenCV Sharpを使用する必要があります。

ただし、OpenCVSharpはNugetから簡単にインストールできるようになっているためできるので、実は非常に簡単に環境構築ができます。

2. テスト環境

OS Windows 7 64bit
開発環境 MicrosoftVisual Studio Community 2017 ver15.6.7
開発言語 Visual C#
OpenCV OpenCV SharpをNugetからインストール

3. プロジェクトの作成

Visual Studio 2017を起動し、「新規作成」→「新しいプロジェクト」→「Visual C#」→「Windowsフォームアプリケーション」を作成する。
注意点として、ご自身の環境のVisual StudionにC#がインストールされてない場合があります。その場合、Visual Studio InstallerからC#の開発環境をインストールしておく必要があります。

4. OpenCV Sharpのインストール

NuGetを利用するのが便利なので、ソリューションエクスプローラーからソリューション名を右クリックし、「NuGetパッケージの管理」を選択。
OpenCVと入力して検索すると、「OpenCvSharp3-AnyCPU.3.4.1.20180319」というパッケージがあるので、インストールを実行する。1~2分するとインストールが完了する。

プロジェクトの参照を開いて、その中に[OpenCvSharp」があれば正常にインストールが完了している。
NuGetからOpenCVSharpをインストールした場合は、[OpenCvSharp」の他に、[OpenCvSharp.Blob」[OpenCvSharp.Extensions」[OpenCvSharp.UserInterfaces」も参照に加えられている。

5. 動作確認

実際にコーディングして動作確認してみる。

(1)Form1.csファイルに以下を追記する。

using OpenCvSharp;

(2)画面(GUI)の作成

Formにボタンを2個配置し、button1を”実行”とし、button2を”終了”とする。
このアプリケーションの動作イメージは、まず、実行ボタンを押すと、画像を読み込んでOpenCVでなんらかの処理を実行する。
そして、終了ボタンを押すと、アプリケーションを終了する、という動作である。

ボタン配置はとりあえずこんな感じ。

(3)実行ボタン(button1)を押下した場合の処理を記述する。

取りあえず、読み込んだ画像に対して、大津方式の二値化処理を実行することとした。

private void button1_Click(object sender, EventArgs e)
{
//画像を読み込む
Mat src = new Mat(@"G:\OpenCV\lenna.png", ImreadModes.GrayScale);

//二値化後画像
Mat dst = src.Clone();

//二値化
Cv2.Threshold(src, dst, 0, 255, ThresholdTypes.Otsu);

//画像の表示
using (new Window("src", WindowMode.AutoSize, src));
using (new Window("dst", WindowMode.AutoSize, dst));

}

なお、4行目のG:\OpenCV\lenna.pngの部分はご自身の環境・画像に合わせて変更してください。

(4)終了(button2)を押下した場合の処理を記述する。

終了ボタンを押したら、アプリケーションを終了するようにする。

 private void button2_Click(object sender, EventArgs e) { this.Close(); } 

6.実行結果

入力画像(元画像)であるsrcと、処理画像であるdstがそれぞれ新しいウィンドウに表示される。

7.改良

これでもいいのだが、せっかくのWindowsフォームアプリケーションなので、GUI上に画像を表示できるようにしてみる。
やり方は色々あるみたいだが、取りあえず結論から。

(1)MatToBitmap関数の追加
GUI上に画像を表示するには、OpenCV上で扱うMat形式をBitmap形式に変換する必要がある。

 public static Bitmap MatToBitmap(Mat image)
        {
            return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(image);
        } // end of MatToBitmap function

(2)実行ボタン(button1)を押下した場合の処理を修正する。

 private void button1_Click(object sender, EventArgs e)
        {
            //openボタンの動作

            //画像を読み込む
            Mat src = new Mat(@"G:\OpenCV\lenna.png", ImreadModes.GrayScale);

            //二値化後画像
            Mat dst = src.Clone();

            //二値化
            Cv2.Threshold(src, dst, 0, 255, ThresholdTypes.Otsu);
            
            //Form に追加した Picture Box と同じサイズではまる Bitmap を生成
            Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            
            //canvas オブジェクト上の Image を操作するために,Graphics オブジェクトを取得
            Graphics g = Graphics.FromImage(canvas);

            // canvas 上での Image 操作の際の補完方法を指定
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;

            //表示する画像
            Bitmap bitimg = MatToBitmap(dst);

            //画像表示位置、サイズを指定する
            g.DrawImage(bitimg, 0, 0, 225, 225);

            //メモリクリア
            bitimg.Dispose();
            g.Dispose();

            //pictureboxに紐付け
            pictureBox1.Image = canvas;

        }

8.改良結果

9.ソースコード


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;

namespace OpenCVSharp3._4._1._20180319_VS2017_dotNet461_test1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

public static Bitmap MatToBitmap(Mat image)
{
return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(image);
} // end of MatToBitmap function

private void button1_Click(object sender, EventArgs e)
{
//openボタンの動作

//画像を読み込む
Mat src = new Mat(@"G:\OpenCV\lenna.png", ImreadModes.GrayScale);

//二値化後画像
Mat dst = src.Clone();

//二値化
Cv2.Threshold(src, dst, 0, 255, ThresholdTypes.Otsu);

//画像の表示
using (new Window("src", WindowMode.AutoSize, src));
using (new Window("dst", WindowMode.AutoSize, dst));

//Form に追加した Picture Box と同じサイズではまる Bitmap を生成
Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);

//canvas オブジェクト上の Image を操作するために,Graphics オブジェクトを取得
Graphics g = Graphics.FromImage(canvas);

// canvas 上での Image 操作の際の補完方法を指定
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;

//表示する画像
Bitmap bitimg = MatToBitmap(dst);

//画像表示位置、サイズを指定する
g.DrawImage(bitimg, 0, 0, 225, 225);

//メモリクリア
bitimg.Dispose();
g.Dispose();

//pictureboxに紐付け
pictureBox1.Image = canvas;

}

private void button2_Click(object sender, EventArgs e)
{
this.Close();
}

}
}

コメント

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