OpenCVSharpのフィルターを試す「AdaptiveThreshold・適応型しきい値による2値化」

コンピュータ

適応型しきい値による2値化

ソースコード

ファイル名:MainWindow.cs



// メインウィンドウ
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using static UI;

using OpenCvSharp;
using OpenCvSharp.WpfExtensions;

namespace ImgFilterAdaptiveThreshold;

public sealed class MainWindow : System.Windows.Window
{
    Mat? _src;
    Mat? _dst;
    bool _filterViewFlag = false;
    Image _img;
    public MainWindow()
    {
        // ドックパネル
        var panel = new DockPanel();
        this.Init("AdaptiveThreshold Sample").Content(panel);

        // イメージコントロール
        _img = UI.Img().OnLeftClick(p =>
        {
            if (_src is null || _dst is null || _img is null) return;
            // 左クリック フィルター前後切替
            if (_filterViewFlag == true)
            {
                _img.Source = _src.ToBitmapSource();
                _filterViewFlag = false;
                this.Title = "フィルター前";
            }
            else
            {
                _img.Source = _dst.ToBitmapSource();
                _filterViewFlag = true;
                this.Title = "フィルター後";
            }
        }).AddTo(panel);

        // D&D
        AllowDrop = true;
        // 画像だけ受け付けて最初の1枚を表示
        Wiring.AcceptFiles(this, files =>
        {
            _src?.Dispose();
            _dst?.Dispose();
            // 画像を読み込み
            _src = Cv2.ImRead(files[0], ImreadModes.Unchanged);

            // _dst = (Mat)_src.Clone();
            _dst = OpenCVFilters.ToAdaptiveThreshold(_src);

            // Mat=>BitmapSource変換
            _img.Source = _dst!.ToBitmapSource();
            _filterViewFlag = true;
            this.Title = "フィルター後";
        },
        ".png", ".jpg", ".jpeg", ".bmp", ".gif", ".webp");
    }
}

ファイル名:OpenCVFilters.cs


using System.ComponentModel;
using OpenCvSharp;
public static class OpenCVFilters
{
    // グレースケール化
    public static Mat ToGray(Mat src)
    {
        if (src.Channels() == 1) return (Mat)src.Clone();

        Mat dst = new();
        if (src.Channels() == 4)
        {
            Cv2.CvtColor(src, dst, ColorConversionCodes.BGRA2GRAY);
        }
        if (src.Channels() == 3)
        {
            Cv2.CvtColor(src, dst, ColorConversionCodes.BGR2GRAY);
        }
        return dst;
    }
    // 適応的しきい値処理による2値化
    public static Mat ToAdaptiveThreshold(Mat src)
    {
        using Mat gray = ToGray(src);
        using Mat work = new();
        Mat dstGray = new();
        
        Cv2.AdaptiveThreshold(gray, work, 255.0,
                    AdaptiveThresholdTypes.GaussianC,
                    ThresholdTypes.BinaryInv,
                    51, 20);
        Cv2.BitwiseNot(work, dstGray);

        return dstGray;
    }
}

実行例

・元画像

・フィルター後の画像

コメント