膨張・収縮フィルタのサンプル
実行環境構築
プロジェクトの作成
mkdir プロジェクト名
cd プロジェクト名
dotnet new winforms
dotnet add package OpenCvSharp4.Windows -v 4.6.0.20220608
dotnet add package OpenCvSharp4.Extensions -v 4.6.0.20220608
code .
ソースプログラム
namespace DilateErodeSample;
using OpenCvSharp;
using OpenCvSharp.Extensions;
public partial class Form1 : Form
{
Mat? _view = null;
public Form1()
{
InitializeComponent();
Text = "膨張・収縮フィルタ";
Size = new System.Drawing.Size(850, 800);
// ベース画像
var fnt = new Font("MS UI Gothic", 24);
var bmp = new Bitmap(800, 600);
using (var g = Graphics.FromImage(bmp))
{
g.FillRectangle(Brushes.White, 0, 0, bmp.Width, bmp.Height);
g.DrawString("こちらにD&D", fnt, Brushes.Green, 0.0f, 0.0f);
}
// スプリットコンテナ(上下)
var ud = new SplitContainer
{
Dock = DockStyle.Fill,
Orientation = Orientation.Horizontal, // 上下
Panel1MinSize = 120,
};
// ピクチャボックス
var picbox = new PictureBox
{
SizeMode = PictureBoxSizeMode.Zoom,
Dock = DockStyle.Fill,
AllowDrop = true,
Image = bmp,
};
// 実行ボタン
var execBtn = new RadioButton
{
Text = "フィルターOFF",
Appearance = Appearance.Button,
AutoCheck = false,
Size = new System.Drawing.Size(180, 50),
};
// 収縮フィルタ回数
var dilateNLabel = new Label
{
Text = "収縮回数:1"
};
var dilateN = new TrackBar
{
Value = 1,
Minimum = 0,
Maximum = 5,
};
// 膨張フィルタ回数
var erodeNLabel = new Label
{
Text = "膨張回数:1"
};
var erodeN = new TrackBar
{
Value = 1,
Minimum = 0,
Maximum = 5,
};
// パネル
var flowPanel = new FlowLayoutPanel
{
Dock = DockStyle.Fill,
};
// ドラッグエンターイベント
picbox.DragEnter += (sender, e) =>
{
if (e.Data == null) return;
if(!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
e.Effect = DragDropEffects.Copy;
};
// ドラッグアンドドロップイベント
picbox.DragDrop += (sender, e) =>
{
if (e.Data == null) return;
var fd = e.Data.GetData(DataFormats.FileDrop);
if (fd == null) return;
string? path = ((string[])fd)[0];
_view?.Dispose();
_view = Cv2.ImRead(path);
picbox.Image?.Dispose();
picbox.Image = BitmapConverter.ToBitmap(_view);
execBtn.Checked = false;
};
// ボタンクリックイベント
execBtn.Click += (sender, e) =>
{
if (_view is null) return;
picbox.Image?.Dispose();
if (execBtn.Checked == true)
{
picbox.Image = BitmapConverter.ToBitmap(_view);
execBtn.Text = "フィルターOff";
execBtn.Checked = false;
} else {
using (var img = new Mat())
using (var element = Cv2.GetStructuringElement(MorphShapes.Ellipse, new OpenCvSharp.Size(3,3)))
{
// RGB=>グレースケール
Cv2.CvtColor(_view, img, ColorConversionCodes.RGB2GRAY);
// 2値化
Cv2.Threshold(img, img, 127.0, 255.0, ThresholdTypes.Binary);
// 収縮
for(int i = 0; i < dilateN.Value; i++)
Cv2.Dilate(img, img, element);
// 膨張
for(int i = 0; i < erodeN.Value; i++)
Cv2.Erode(img, img, element);
picbox.Image = BitmapConverter.ToBitmap(img);
}
execBtn.Text = "フィルターOn";
execBtn.Checked = true;
}
};
// 収縮フィルタ回数変更イベント
dilateN.ValueChanged += (s, e) =>
{
dilateNLabel.Text = string.Format("収縮回数:{0}", dilateN.Value);
};
// 膨張フィルタ回数変更イベント
erodeN.ValueChanged += (s, e) =>
{
erodeNLabel.Text = string.Format("膨張回数:{0}", erodeN.Value);
};
// コントロールの追加
ud.Panel1.Controls.Add(picbox);
flowPanel.Controls.AddRange(new Control[]
{
execBtn,
dilateNLabel,
dilateN,
erodeNLabel,
erodeN,
});
ud.Panel2.Controls.Add(flowPanel);
Controls.Add(ud);
}
}
実行
dotnet run
画像ファイルをドラックアンドドロップ
フィルター実行:収縮0回膨張0回、グレースケール→2値化のみ
フィルター実行:収縮1回膨張1回、面積の小さな黒部分が白に置き換わっている。
フィルター実行:収縮1回膨張0回、黒部分が小さくなっている
フィルター実行:収縮0回膨張1回、黒部分が大きくなっている
コメント