BitwiseAND,OR,XOR,NOTのサンプル
実行環境構築
プロジェクトの作成
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 BitwiseAndSample;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Text = "bitwise";
// ベース画像
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("結果", fnt, Brushes.Black, 0.0f, 0.0f);
}
var errBitmap = new Bitmap(800, 600);
using (var g = Graphics.FromImage(errBitmap))
{
g.FillRectangle(Brushes.White, 0, 0, errBitmap.Width, errBitmap.Height);
g.DrawString("画像のサイズが異なります。", fnt, Brushes.Black, 0.0f, 0.0f);
}
var aBitmap = new Bitmap(800, 600);
using (var g = Graphics.FromImage(aBitmap))
{
g.FillRectangle(Brushes.White, 0, 0, aBitmap.Width, aBitmap.Height);
g.DrawString("A:画像をD&D", fnt, Brushes.Black, 0.0f, 0.0f);
}
var bBitmap = new Bitmap(800, 600);
using (var g = Graphics.FromImage(bBitmap))
{
g.FillRectangle(Brushes.White, 0, 0, bBitmap.Width, bBitmap.Height);
g.DrawString("B:画像をD&D", fnt, Brushes.Black, 0.0f, 0.0f);
}
// スプリットコンテナ
var scViewConsole = new SplitContainer
{
Dock = DockStyle.Fill,
Orientation = Orientation.Horizontal, // 上下
Panel1MinSize = 120,
};
// スプリットコンテナ
var scInOut = new SplitContainer
{
Dock = DockStyle.Fill,
Orientation = Orientation.Vertical, // 左右
Panel1MinSize = 240,
};
// スプリットコンテナ
var scAb = new SplitContainer
{
Dock = DockStyle.Fill,
Orientation = Orientation.Horizontal, // 上下
Panel1MinSize = 120,
};
// ピクチャボックス
var picboxResult = new PictureBox
{
SizeMode = PictureBoxSizeMode.AutoSize,
Image = (Bitmap)resultBitmap.Clone(),
};
// ピクチャボックス
var picboxA = new PictureBox
{
SizeMode = PictureBoxSizeMode.AutoSize,
Image = aBitmap,
};
// ピクチャボックス
var picboxB = new PictureBox
{
SizeMode = PictureBoxSizeMode.AutoSize,
Image = bBitmap,
};
// パネル
var flowPanel = new FlowLayoutPanel
{
Dock = DockStyle.Fill,
};
// グレースケールチェックボックス
var grayChkbox = new CheckBox
{
Checked = true,
Text = "グレースケール",
};
// ANDボタン
var andButton = new Button
{
Text = "AND",
Size = new System.Drawing.Size(180, 50),
};
// ORボタン
var orButton = new Button
{
Text = "OR",
Size = new System.Drawing.Size(180, 50),
};
// XORボタン
var xorButton = new Button
{
Text = "XOR",
Size = new System.Drawing.Size(180, 50),
};
// NOT_Aボタン
var notAButton = new Button
{
Text = "NOT_A",
Size = new System.Drawing.Size(180, 50),
};
// NOT_Bボタン
var notBButton = new Button
{
Text = "NOT_B",
Size = new System.Drawing.Size(180, 50),
};
// コントロールの追加
flowPanel.Controls.AddRange(new Control[]
{
grayChkbox,
andButton,
orButton,
xorButton,
notAButton,
notBButton,
});
scAb.Panel1.Controls.Add(picboxA);
scAb.Panel1.AutoScroll = true;
scAb.Panel1.AllowDrop = true;
scAb.Panel2.Controls.Add(picboxB);
scAb.Panel2.AutoScroll = true;
scAb.Panel2.AllowDrop = true;
scInOut.Panel1.Controls.Add(picboxResult);
scInOut.Panel1.AutoScroll = true;
scInOut.Panel1.AllowDrop = false;
scInOut.Panel2.Controls.Add(scAb);
scViewConsole.Panel1.Controls.Add(scInOut);
scViewConsole.Panel2.Controls.Add(flowPanel);
Controls.Add(scViewConsole);
// イベント
// ドラッグエンターイベント
scAb.Panel1.DragEnter += (sender, e) =>
{
if (e.Data == null) return;
if(!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
e.Effect = DragDropEffects.Copy;
};
// ドラッグアンドドロップイベント
scAb.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];
picboxA.Image?.Dispose();
using(var fs = new FileStream(path, FileMode.Open))
{
picboxA.Image = new Bitmap(fs);
}
};
// ドラッグエンターイベント
scAb.Panel2.DragEnter += (sender, e) =>
{
if (e.Data == null) return;
if(!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
e.Effect = DragDropEffects.Copy;
};
// ドラッグアンドドロップイベント
scAb.Panel2.DragDrop += (sender, e) =>
{
if (e.Data == null) return;
var fd = e.Data.GetData(DataFormats.FileDrop);
if (fd == null) return;
string? path = ((string[])fd)[0];
picboxB.Image?.Dispose();
using(var fs = new FileStream(path, FileMode.Open))
{
picboxB.Image = new Bitmap(fs);
}
};
// ANDボタンをクリック
andButton.Click += (s, e) =>
{
if (picboxA.Image.Width != picboxB.Image.Width || picboxA.Image.Height != picboxB.Image.Height)
{
picboxResult.Image?.Dispose();
picboxResult.Image = (Bitmap)errBitmap.Clone();
return;
}
using var a = BitmapConverter.ToMat((Bitmap)picboxA.Image);
using var b = BitmapConverter.ToMat((Bitmap)picboxB.Image);
using var result = new Mat();
if (grayChkbox.Checked && a.Channels() > 1)
Cv2.CvtColor(a, a, ColorConversionCodes.RGB2GRAY);
if (grayChkbox.Checked && b.Channels() > 1)
Cv2.CvtColor(b, b, ColorConversionCodes.RGB2GRAY);
Cv2.BitwiseAnd(a, b, result);
picboxResult.Image?.Dispose();
picboxResult.Image = BitmapConverter.ToBitmap(result);
};
// ORボタンをクリック
orButton.Click += (s, e) =>
{
if (picboxA.Image.Width != picboxB.Image.Width || picboxA.Image.Height != picboxB.Image.Height)
{
picboxResult.Image?.Dispose();
picboxResult.Image = (Bitmap)errBitmap.Clone();
return;
}
using var a = BitmapConverter.ToMat((Bitmap)picboxA.Image);
using var b = BitmapConverter.ToMat((Bitmap)picboxB.Image);
using var result = new Mat();
if (grayChkbox.Checked && a.Channels() > 1)
Cv2.CvtColor(a, a, ColorConversionCodes.RGB2GRAY);
if (grayChkbox.Checked && b.Channels() > 1)
Cv2.CvtColor(b, b, ColorConversionCodes.RGB2GRAY);
Cv2.BitwiseOr(a, b, result);
picboxResult.Image?.Dispose();
picboxResult.Image = BitmapConverter.ToBitmap(result);
};
// XORボタンをクリック
xorButton.Click += (s, e) =>
{
if (picboxA.Image.Width != picboxB.Image.Width || picboxA.Image.Height != picboxB.Image.Height)
{
picboxResult.Image?.Dispose();
picboxResult.Image = (Bitmap)errBitmap.Clone();
return;
}
using var a = BitmapConverter.ToMat((Bitmap)picboxA.Image);
using var b = BitmapConverter.ToMat((Bitmap)picboxB.Image);
using var result = new Mat();
if (grayChkbox.Checked && a.Channels() > 1)
Cv2.CvtColor(a, a, ColorConversionCodes.RGB2GRAY);
if (grayChkbox.Checked && b.Channels() > 1)
Cv2.CvtColor(b, b, ColorConversionCodes.RGB2GRAY);
Cv2.BitwiseXor(a, b, result);
picboxResult.Image?.Dispose();
picboxResult.Image = BitmapConverter.ToBitmap(result);
};
// NOT_Aボタンをクリック
notAButton.Click += (s, e) =>
{
using var a = BitmapConverter.ToMat((Bitmap)picboxA.Image);
using var result = new Mat();
if (grayChkbox.Checked && a.Channels() > 1)
Cv2.CvtColor(a, a, ColorConversionCodes.RGB2GRAY);
Cv2.BitwiseNot(a, result);
picboxResult.Image?.Dispose();
picboxResult.Image = BitmapConverter.ToBitmap(result);
};
// NOT_Bボタンをクリック
notBButton.Click += (s, e) =>
{
using var b = BitmapConverter.ToMat((Bitmap)picboxB.Image);
using var result = new Mat();
if (grayChkbox.Checked && b.Channels() > 1)
Cv2.CvtColor(b, b, ColorConversionCodes.RGB2GRAY);
Cv2.BitwiseNot(b, result);
picboxResult.Image?.Dispose();
picboxResult.Image = BitmapConverter.ToBitmap(result);
};
}
}
実行
dotnet run
使い方
A:及びB:に画像をドラッグアンドドロップ。
高さ及び幅が異なる画像は不可。カラー画像はグレースケールに変換されます。
AND,OR,XOR,NOT_A,NOT_Bの各ボタンを押すと論理演算された結果が表示されます。
問題点
カラー画像とグレースケール画像で処理を実行するとエラーになります。
RGBの各チャンネル毎に処理する必要があると思われます。
コメント