2014年1月26日日曜日

様々な色領域のラベリング

人間の顔や手などを認識するのに、前処理として肌色を検出する。

RGBでなくHSVやYCbCr空間を使用すると安定して肌色を検出できることがよく知られている。

HSV


H:色相(Hue)
S:彩度(Saturation)
V:明度(Value)

H色相は、赤っぽい、青っぽいといった「色あい」を表す。
色相を環状に並べたものを色相環といい、赤は 0°、黄色は 60°といったように円上の角度で色あいを示す。

S彩度は「鮮やかさ」を表す。
色相が同じでも、彩度が高ければ鮮やかに見え、低ければグレーに近くなる。
彩度がゼロの場合は無彩色(黒、グレー、白)になります。

V明度は「明るさ」を表す。
明度が高ければ明るい色に、低ければ暗い色になる。

・S と V を固定し H を遷移させて虹色のグラデーションを生み出す
・S を 1.0、 V を 1.0 に固定し H を乱数で決めることで、グレーや黒といった無彩色を避けながらランダムな色を作り出す(逆に無彩色だけを選ぶことも。) 
※参考 http://www.demoscene.jp/?p=1460

以下、変換式。

H =
60 × (G - B) / (Max - Min), if Max = R
60 × (B - R) / (Max - Min), if Max = G
60 × (B - G) / (Max - Min), if Max = B

S = (Max - Min) / Max 

V=Max


YCbCr

Y:輝度
Cb、Cr:色差


Y = 0.299 × R + 0.587 × G + 0.114 × B
Cb = -0.172 × R - 0.339 × G + 0.511 × B
Cr = 0.511 × R - 0.428 × G + 0.083 × B

※係数は視覚度特性による。


肌色


(H < 50 || H > 210) かつ (-50 < Cb && Cb < -20) かつ (20 < Cr && Cr < 40)



白い紙に印刷された黒い文字をラベリングするにはどうしたらよいだろうか。
SとVを低く抑えたフィルターをかけてみるか。


画像のラベリング

画像のラベリングのサンプル。

画像のラベリングのスタンダードな手法は 2 つある。

1. 再帰処理


2. 接続表


1. は注目画素から探索範囲を膨張して、背景画素や探索範囲の境界に到達したら収束させる処理を、全ての画素に対して行う。
背景画素が少ない場合の探索では、画素×画素程度の計算量が必要になりそう。


2. は探索は全画素数の2~3倍程度で良さそう。1回目は、注目画素が抽出した物体画素だった場合に、4または8近傍を探索して、ラベル付けされていなければ ラベル番号n +1を振り、ラベル付けされていれば ラベル番号nを振る処理をラスター処理する。
2回目は、各画素の4または8近傍に対し、自分自身のラベルnよりも小さいラベルmが降られているか、振られていれば、nをすべて、小さいラベルmに置き換える。この処理をラスター処理する。
最後は、ラベルを小さい方から順に詰める処理をラベルの中で行う。


以下、コード。