OpenCVSharp「ノンローカルミーンフィルタ(カラー)」を試す。

C# コンピュータ
C#

プロジェクトの作成

ソースプログラム

using OpenCvSharp;
using OpenCvSharp.Extensions;

namespace FastNlMeansDenoisingColoredSample;

public partial class Form1 : Form
{
    Bitmap? bmp = null;

    // フィルター(ノンローカルミーンフィルタ、カラー)
    static Bitmap Filter(Bitmap b, float h)
    {
        using var mat = BitmapConverter.ToMat(b);
        Cv2.FastNlMeansDenoisingColored(mat, mat, h);
        return BitmapConverter.ToBitmap(mat);
    }

    public Form1()
    {
        InitializeComponent();

        Text = "ノンローカルミーンフィルタ、カラー";

        var sc = new SplitContainer {
            Dock = DockStyle.Fill,
            Orientation = Orientation.Horizontal,   // 上下
            Panel1MinSize = 100,
        };
        var picbox = new PictureBox {
            Dock = DockStyle.Fill,
            AllowDrop = true,
            SizeMode = PictureBoxSizeMode.Zoom,
            Image = bmp,
        };
        picbox.DragEnter += (o, e) => {
            if (e.Data == null) return;
            if(!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
            e.Effect = DragDropEffects.Copy;
        };
        var toClip = new Button {
            Text = "コピー",
            Location = new System.Drawing.Point(10, 10),
            Size = new System.Drawing.Size(180, 50),
            Enabled = false,
        };
        var fromClip = new Button {
            Text = "貼り付け",
            Location = new System.Drawing.Point(200, 10),
            Size = new System.Drawing.Size(180, 50),
            Enabled = true,
        };
        var filterExec = new RadioButton {
            Text = "フィルターOFF",
            Appearance = Appearance.Button,
            AutoCheck = false,
            Location = new System.Drawing.Point(410, 10),
            Size = new System.Drawing.Size(180, 50),
            Enabled = false,
        };
        var hLabel = new Label {
            Text = "H:3",
            Location = new System.Drawing.Point(10, 80),
            Size = new System.Drawing.Size(120, 50),
        };
        var hTrack = new TrackBar {
            Minimum = 1,
            Maximum = 20,
            Value = 3,
            Location = new System.Drawing.Point(80, 80),
            Size = new System.Drawing.Size(360, 50),
        };
        var statusLabel = new ToolStripStatusLabel();
        var statusBar = new StatusStrip();
        statusBar.Items.Add(statusLabel);

        picbox.DragDrop += async (sender, e) => {
            // ファイルドロップ
            if (e.Data == null) return;
            if(!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            if (files.Length < 1) return;

            // 読み込み
            if (picbox.Image != null) picbox.Image.Dispose();
            await Task.Run(()=>{
                using var fs = new System.IO.FileStream(
                    files[0], System.IO.FileMode.Open,  System.IO.FileAccess.Read);
                bmp = (Bitmap)System.Drawing.Image.FromStream(fs);
            });
            if (bmp != null) {
                picbox.Image = (Bitmap)bmp.Clone();
                toClip.Enabled = true;
                filterExec.Enabled = true;
            }
        };
        toClip.Click += (sender, e) => {
            toClip.Enabled = false;
            Clipboard.SetImage(picbox.Image);
            toClip.Enabled = true;
        };
        fromClip.Click += (sender, e) => {

            var img = Clipboard.GetImage();
            if (img == null) return;

            fromClip.Enabled = false;
            if (bmp != null) bmp.Dispose();
            bmp = (Bitmap)img;
            if (picbox.Image != null) picbox.Image.Dispose();
            picbox.Image = (Image)bmp.Clone();
            fromClip.Enabled = true;
            toClip.Enabled = true;
            filterExec.Enabled = true;
        };
        hTrack.ValueChanged += (sender, e) => {
            hLabel.Text = "H:" + hTrack.Value.ToString();
        };
        filterExec.Click += async (sender, e) => {
            filterExec.Enabled = false;

            filterExec.Checked = !filterExec.Checked;
            if (picbox.Image != null) picbox.Image.Dispose();
            
            if (filterExec.Checked) {
                // フィルター
                float h = (float)hTrack.Value;
                if (bmp != null) {
                    Bitmap? result = null;
                    var sw = new System.Diagnostics.Stopwatch();
                    sw.Start();
                    await Task.Run(()=>{
                        result = Filter(bmp, h);
                    });
                    sw.Stop();
                    if (result != null) {
                        picbox.Image = result;
                        filterExec.Text = "フィルターON";
                        statusLabel.Text = $"処理時間:{sw.ElapsedMilliseconds}ミリ秒";
                    }
                }
            } else {
                if (bmp != null ) {
                    picbox.Image = (Bitmap)bmp.Clone();
                    filterExec.Text = "フィルターOFF";
                    statusLabel.Text = "";
                }
            }


            filterExec.Enabled = true;
        };
        sc.Panel1.Controls.Add(picbox);
        sc.Panel2.Controls.Add(toClip);
        sc.Panel2.Controls.Add(fromClip);
        sc.Panel2.Controls.Add(filterExec);
        sc.Panel2.Controls.Add(hLabel);
        sc.Panel2.Controls.Add(hTrack);
        Controls.Add(sc);
        Controls.Add(statusBar);

        this.FormClosed += (sender, o) => {
            if (bmp != null) bmp.Dispose();
        };
        this.Size = new System.Drawing.Size(800, 600);
    }
}

実行

dotnet run

コメント