目次
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(); } } }
コメント