LUTを使って減色処理を行います。
ソースコード
ファイル名:Form1.DietColor.cs(新規追加)
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace GazouKakou02;
public partial class Form1 : Form
{
// メニュー項目
readonly ToolStripMenuItem dietColorMenuItem = new()
{
Text = "減色",
};
/// <summary>
/// 減色の初期化
/// </summary>
public void Init_DietColor()
{
// メニューの登録
filterMenuItem.DropDownItems.Add(dietColorMenuItem);
// フィルター(減色)
Func<Bitmap, int, Task<Bitmap>> filter = new(async (src, n) =>
{
return await Task.Run(()=>
{
using Mat srcMat = BitmapConverter.ToMat(src);
using Mat dstMat = new();
byte[] lut = new byte[256];
int x = lut.Length;
int div = x / n;
int min = 0;
int max = x - 1;
int center = x / 2;
for(int i=0; i < lut.Length; i++)
{
int a = i / div;
int b;
if (i < center)
{
b = a * div - 1;
} else {
b = (a + 1) * div - 1;
}
b = (b < min) ? min : b;
b = (b > max) ? max : b;
lut[i] = (byte)b;
}
Cv2.LUT(srcMat, lut, dstMat);
return BitmapConverter.ToBitmap(dstMat);
});
});
// メニューアイテムのクリックイベント
dietColorMenuItem.Click += (s, e) =>
{
if (_buffBmp is null) return;
var dialog = new FilterDialog();
dialog.Load += (s, e) =>
{
dialog.Track1.Value = 8;
dialog.Track1.Maximum = 256;
dialog.Track1.Minimum = 1;
};
bool filterFlag = false;
Bitmap? bmp = null;
dialog.Track1.ValueChanged += async (s, e) =>
{
dialog.Track1Label.Text = string.Format("n:{0}", dialog.Track1.Value);
if (filterFlag)
{
// フィルター実行中につきキャンセル
return;
}
filterFlag = true;
dialog.OkBtn.Enabled = !filterFlag;
var backupValue = dialog.Track1.Value;
var currentValue = backupValue;
do
{
backupValue = currentValue;
int n = currentValue;
bmp = await filter(_buffBmp, n);
dialog.Picbox.Image?.Dispose();
dialog.Picbox.Image = bmp;
currentValue = dialog.Track1.Value;
} while( currentValue != backupValue);
filterFlag = false;
dialog.OkBtn.Enabled = !filterFlag;
};
if (dialog.ShowDialog() == DialogResult.OK)
{
// OK
this.Bmp = bmp;
} else {
// Cancel
bmp?.Dispose();
}
};
}
}
実行
画像が表示されている状態でメインメニュー「フィルター」→「減色」を選ぶ
注)グレースケールでの動作を想定してるのでカラー画像での場合動作は未確認
解説
OpenCVにはk-means法を使った減色用のメソッドがあるのですが、OpenCVSharpでの使い方を筆者は理解していません。
ということで、今回はLUTを使い減色処理を行ってみました。LUTで色を置き換えるテーブルを減色されるように値をセットしてあります。
アルゴリズムとしては0~255の数字に対して減色したい色数を割り算して求めています。ただし、最小値が0最大値が255になるように調整しており、指定の色数を超える可能性があります。
コメント