OpenCVSharp「チャンネルの分離、結合」を試す。

コンピュータ
SplitとMergeのサンプル

実行環境構築

プロジェクトの作成

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 .

ソースプログラム

using OpenCvSharp;
using OpenCvSharp.Extensions;

namespace SplitMargeSample;
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        
        Text = "チャンネル分割結合";
        
        Mat[] ch = new Mat[4] {new Mat(), new Mat(), new Mat(), new Mat()};

        // ベース画像
        var fnt = new Font("MS UI Gothic", 24);
        var resultBitmap = new Bitmap(800, 600);
        using (var g = Graphics.FromImage(resultBitmap))
        {
            g.FillRectangle(Brushes.White, 0, 0, resultBitmap.Width, resultBitmap.Height);
            g.DrawString("D&D", fnt,  Brushes.Coral, 0.0f, 0.0f);
        }

        var mat = BitmapConverter.ToMat(resultBitmap);
        Cv2.Split(mat, out ch);

        // スプリットコンテナ
        var scViewConsole = new SplitContainer
        {
            Dock = DockStyle.Fill,
            Orientation = Orientation.Horizontal,   // 上下
            Panel1MinSize = 120,
        };
        // ピクチャボックス
        var picbox = new PictureBox
        {
            SizeMode = PictureBoxSizeMode.AutoSize,
            Image = (Bitmap)resultBitmap.Clone(),
        };
        // パネル
        var flowPanel = new FlowLayoutPanel
        {
            Dock = DockStyle.Fill,
        };
        // Rボタン
        var rButton = new Button
        {
            Text = "赤",
            Size = new System.Drawing.Size(180, 50),
        };
        // Gボタン
        var gButton = new Button
        {
            Text = "緑",
            Size = new System.Drawing.Size(180, 50),
        };
        // Bボタン
        var bButton = new Button
        {
            Text = "青",
            Size = new System.Drawing.Size(180, 50),
        };
        // Mergeボタン
        var mergeButton = new Button
        {
            Text = "結合",
            Size = new System.Drawing.Size(180, 50),
        };
        // コントロールの登録
        flowPanel.Controls.AddRange(new Control[]
        {
            rButton,
            gButton,
            bButton,
            mergeButton,
        });

        scViewConsole.Panel1.Controls.Add(picbox);
        scViewConsole.Panel1.AllowDrop = true;
        scViewConsole.Panel1.AutoScroll = true;

        scViewConsole.Panel2.Controls.Add(flowPanel);

        Controls.Add(scViewConsole);

        // イベント

        // Rボタンクリック
        rButton.Click += (s, e) =>
        {
            picbox.Image?.Dispose();
            picbox.Image = BitmapConverter.ToBitmap(ch[2]);
        };
        // Gボタンクリック
        gButton.Click += (s, e) =>
        {
            picbox.Image?.Dispose();
            picbox.Image = BitmapConverter.ToBitmap(ch[1]);
        };
        // Bボタンクリック
        bButton.Click += (s, e) =>
        {
            picbox.Image?.Dispose();
            picbox.Image = BitmapConverter.ToBitmap(ch[0]);
        };
        // Merageボタンクリック
        mergeButton.Click += (s, e) =>
        {
            picbox.Image?.Dispose();
            using var dst = new Mat();
            Cv2.Merge(ch, dst);
            picbox.Image = BitmapConverter.ToBitmap(dst);
        };

        // ドラッグエンターイベント
        scViewConsole.Panel1.DragEnter += (sender, e) =>
        {
            if (e.Data == null) return;
            if(!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
            e.Effect = DragDropEffects.Copy;
        };
        // ドラッグアンドドロップイベント
        scViewConsole.Panel1.DragDrop += (sender, e) =>
        {
            if (e.Data == null) return;
            var fd = e.Data.GetData(DataFormats.FileDrop);
            if (fd == null) return;
            string? path = ((string[])fd)[0];
            picbox.Image?.Dispose();
            using(var fs = new FileStream(path, FileMode.Open))
            {
                picbox.Image = new Bitmap(fs);
            }
            using var src = BitmapConverter.ToMat((Bitmap)picbox.Image);
            Cv2.Split(src, out ch);
        };
    }
}

実行

dotnet run
「赤」、「緑」、「青」の各ボタンを押すと各チャンネルの内容がグレースケールで表示されます。
「結合」ボタンを押すと各チャンネルが結合されたカラー画像が表示されます。
分離
Cv2.Split(src, out ch);
結合
Cv2.Merge(ch, dst);

chはMatの配列
Mat[] ch = new Mat[4] {new Mat(), new Mat(), new Mat(), new Mat()};

コメント