OpenCVSharp「バイラテラルフィルタ」を試す。

コンピュータ

BilateralFilter()のサンプルです。

実行環境構築

プロジェクトの作成

mkdir プロジェクト名
cd プロジェクト名
dotnet new winforms
dotnet add package OpenCvSharp4.Windows
dotnet add package OpenCvSharp4.Extensions
code .

ソースプログラム

namespace BilateralFilterSample;

using OpenCvSharp;
using OpenCvSharp.Extensions;
public partial class Form1 : Form
{
    Mat? view = null;

    static Mat filter(Mat src, int d, double sigmaColor, double sigmaSpace)
    {
        Mat result = src.Clone();
        Cv2.BilateralFilter(src, result, d, sigmaColor, sigmaSpace);
        return result;
    }
    public Form1()
    {
        InitializeComponent();

        Text = "バイラテラルフィルタ";
        Size = new System.Drawing.Size(850, 800);

        var fnt = new Font("MS UI Gothic", 12);
        var vb = new Bitmap(800, 600);
        using (var g = Graphics.FromImage(vb)) {
            g.FillRectangle(Brushes.White, 0, 0, vb.Width, vb.Height);
            g.DrawString("こちらにD&D Or Ctrl+Cコピー Ctrl+V貼り付け", fnt,  Brushes.Green, 0.0f, 0.0f);
        }
        
        var ud = new SplitContainer {
            Dock = DockStyle.Fill,
            Orientation = Orientation.Horizontal,   // 上下
            Panel1MinSize = 120,
        };
        var picboxV = new PictureBox {
            SizeMode = PictureBoxSizeMode.Zoom,
            Dock = DockStyle.Fill,
            
            AllowDrop = true,
            Image = vb,
        };
        var defaultButtonSize = new System.Drawing.Size(120, 50);
        var execBtn = new RadioButton {
            Text = "フィルターOFF",
            Appearance = Appearance.Button,
            AutoCheck = false,
            Size = defaultButtonSize,
        };
        var flowPanel = new FlowLayoutPanel { Dock = DockStyle.Fill, };
        
        var defaultLabelSize = new System.Drawing.Size(160, 50);
        var defaultTrackSize = new System.Drawing.Size(160, 50);

        int d = 15;
        var dLabel = new Label { Text = "D:"+d, Size = defaultLabelSize, };
        var dTrack = new TrackBar {
            Minimum = 1, Maximum = 100, Value = d,
            Size = defaultTrackSize, };
        dTrack.ValueChanged += (sender, e) => {
            d = dTrack.Value;
            dLabel.Text = "D:" + d;
        };

        int sigmaColor = 50;
        var sigmaColorLabel = new Label { Text = "sigmaColor:"+sigmaColor, Size = defaultLabelSize, };
        var sigmaColorTrack = new TrackBar {
            Minimum = 1, Maximum = 100, Value = sigmaColor,
            Size = defaultTrackSize, };
        sigmaColorTrack.ValueChanged += (sender, e) => {
            sigmaColor = sigmaColorTrack.Value;
            sigmaColorLabel.Text = "sigmaColor:" + sigmaColor;
        };

        int sigmaSpace = 20;
        var sigmaSpaceLabel = new Label { Text = "sigmaSpace:"+sigmaSpace, Size = defaultLabelSize, };
        var sigmaSpaceTrack = new TrackBar {
            Minimum = 1, Maximum = 100, Value = sigmaSpace,
            Size = defaultTrackSize, };
        sigmaSpaceTrack.ValueChanged += (sender, e) => {
            sigmaSpace = sigmaSpaceTrack.Value;
            sigmaSpaceLabel.Text = "sigmaSpace:" + sigmaSpace;
        };

        picboxV.DragEnter += (sender, e) => {
            if (e.Data == null) return;
            if(!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
            e.Effect = DragDropEffects.Copy;
        };
        picboxV.DragDrop += (sender, e) => {
            if (e.Data == null) return;
            var fd = e.Data.GetData(DataFormats.FileDrop);
            if (fd == null) return;
            string? path = ((string[])fd)[0];
            if (view is not null) view.Dispose();
            view = Cv2.ImRead(path);
            if (picboxV.Image is not null) picboxV.Image.Dispose();
            picboxV.Image = BitmapConverter.ToBitmap(view);
            execBtn.Checked = false;
        };
        execBtn.Click += async (sender, e) => {
            if (view is null) return;
            if (execBtn.Checked == true) {
                if (picboxV.Image is not null) picboxV.Image.Dispose();
                picboxV.Image = BitmapConverter.ToBitmap(view);

                execBtn.Text = "フィルターOff";
                execBtn.Checked = false;
            } else {
                await Task.Run(()=>{
                    using (var result = filter(view, d, sigmaColor, sigmaSpace)) {
                        if (picboxV.Image is not null) picboxV.Image.Dispose();
                        picboxV.Image = BitmapConverter.ToBitmap(result);
                    }
                });

                execBtn.Text = "フィルターOn";
                execBtn.Checked = true;
            }            
        };
        KeyPreview = true;
        KeyDown += (sender, e) => {
            if (e.KeyData == (Keys.Control | Keys.C)) {
                // コピー                
                if (picboxV.Image is null) return;
                var ms = new MemoryStream();
                picboxV.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                Clipboard.SetData("PNG", ms);            
            } else if (e.KeyData == (Keys.Control | Keys.V)) {
                // 貼り付け
                var obj = Clipboard.GetData("PNG");
                if (obj == null) return;
                var ms = (MemoryStream)obj;
                if (ms is null) return;
                if (view is not null) view.Dispose();
                using(var b = new Bitmap(ms)) {
                    view = BitmapConverter.ToMat(b);
                }
                if (picboxV.Image is not null) picboxV.Image.Dispose();
                picboxV.Image = BitmapConverter.ToBitmap(view);
                execBtn.Checked = false;
            }
        };

        ud.Panel1.Controls.Add(picboxV);
        flowPanel.Controls.AddRange(new Control[]{
            execBtn, dLabel, dTrack, sigmaColorLabel, sigmaColorTrack, sigmaSpaceLabel, sigmaSpaceTrack});
        ud.Panel2.Controls.Add(flowPanel);
        Controls.Add(ud);
    }
}

実行

dotnet run

コメント