A certain engineer "COMPLEX"

開発メモ その26 特定の色相を選択して抜き出す

HSVを使って特定の色だけ残す


前回、RGBと違ってRGBは色相によって同じような色を選択できることを説明しました。
これを用いて、実際に画像から特定の色だけを残してみます。

処理としては単純で、入力画像の各画素をRGBからHSVに変換し、指定した条件に合致していたら、その画素を残し、それ以外なら任意の色で塗りつぶします。
下記のサンプルでは、byte配列上の画素をHSVに変換し、最小、最大の色相、彩度、明度を指定し、その範囲チェックをしています。
また今回は白で塗りつぶしを実施しています。


private void UpdateImage()
{
unsafe
{
fixed (byte* pSrc = &this._ImageBuffer[0])
fixed (byte* pDst = &this._FilteredImageBuffer[0])
{
var ps = pSrc;
var pd = pDst;

var stride = this._Stride;
var width = this._Width;
var height = this._Height;
var channel = this._Channel;
var dpiX = this._OriginalSource.DpiX;
var dpiY = this._OriginalSource.DpiY;
var offset = stride / channel - width;

var maxHue = this._MaxHue;
var minHue = this._MinHue;
var maxSaturation = this._MaxSaturation;
var minSaturation = this._MinSaturation;
var maxValue = this._MaxValue;
var minValue = this._MinValue;

float h, s, v;
byte back = 255;
for (var y = 0; y < height; y++)
{
for (var x = 0; x < width; x++, pd += channel, ps += channel)
{
FromRgb(ps[2], ps[1], ps[0], out h, out s, out v);
if (minHue <= h && h <= maxHue &&
minSaturation <= s && s <= maxSaturation &&
minValue <= v && v <= maxValue)
{
pd[2] = ps[2];
pd[1] = ps[1];
pd[0] = ps[0];
}
else
{
// 白にする
pd[2] = back;
pd[1] = back;
pd[0] = back;
}
}

pd += offset;
ps += offset;
}

var bitmap = BitmapSource.Create(
width,
height,
dpiX,
dpiY,
this._PixelFormat,
null,
this._FilteredImageBuffer,
stride);
bitmap.Freeze();
this.FilteredSource = bitmap;
}
}
}

上記のサンプルを使ったのが下記のサンプルです。
サンプルに使った画像は Public Domain Pictures.net から利用させていただきました。

上のサンプルでは色相の10-60はオレンジと黄色を表しており、明度と彩度は明るく、純度の高い色を選択しています。
詳しい色相の説明は下記のページがわかりやすいです。

Source Code

https://github.com/takuya-takeuchi/Demo/tree/master/Image3

コメントを残す

メールアドレスが公開されることはありません。

%d人のブロガーが「いいね」をつけました。