OpenCVSharpのフィルターを試す「グレースケール化」

コンピュータ

OpneCVSharpのフィルターを試すだけのサンプルコードをWPFで作ろうと思います。

ソースコード

ファイル名:ImgFilterGray.csproj


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="OpenCvSharp4" Version="4.11.0.20250507" />
    <PackageReference Include="OpenCvSharp4.runtime.win" Version="4.11.0.20250507" />
    <PackageReference Include="OpenCvSharp4.WpfExtensions" Version="4.11.0.20250507" />
  </ItemGroup>

</Project>

ファイル名:AppEntry.cs


using System;
using System.Windows;

namespace ImgFilterGray
{
    public class AppEntry: Application
    {
        [STAThread] public static void Main()
             => new AppEntry().Run(new MainWindow());
    }
}

ファイル名: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 ImgFilterGray;

public sealed class MainWindow : System.Windows.Window
{
    Mat? _src;
    Mat? _dst;
    bool _filterViewFlag = false;
    Image _img;
    public MainWindow()
    {
        // ドックパネル
        var panel = new DockPanel();
        this.Init("OpenCVFilter 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.ToGray(_src);

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

ファイル名:OpenCVFilters.cs


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;
    }
}

使い方

実行後、表示されるウィンドウにエクスプローラーから画像ファイルをドラックアンドドロップします。
そうしますと、フィルター処理された画像が表示されます。
画像を左クリックするとフィルター前の画像と切り替わります。
機能的にはそれだけに絞り込みました。

今回は画像をグレースケール化するフィルターにしましたが、フィルターとフィルターの呼び出し部分を差し替えて色々なフィルターを試してみるつもりです。

実行例

・元画像

・フィルター後の画像

コメント