RGBでなくHSVやYCbCr空間を使用すると安定して肌色を検出できることがよく知られている。
HSV
H:色相(Hue)
S:彩度(Saturation)
V:明度(Value)
H色相は、赤っぽい、青っぽいといった「色あい」を表す。
色相を環状に並べたものを色相環といい、赤は 0°、黄色は 60°といったように円上の角度で色あいを示す。
S彩度は「鮮やかさ」を表す。
色相が同じでも、彩度が高ければ鮮やかに見え、低ければグレーに近くなる。
彩度がゼロの場合は無彩色(黒、グレー、白)になります。
V明度は「明るさ」を表す。
明度が高ければ明るい色に、低ければ暗い色になる。
・S と V を固定し H を遷移させて虹色のグラデーションを生み出す※参考 http://www.demoscene.jp/?p=1460
・S を 1.0、 V を 1.0 に固定し H を乱数で決めることで、グレーや黒といった無彩色を避けながらランダムな色を作り出す(逆に無彩色だけを選ぶことも。)
以下、変換式。
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を低く抑えたフィルターをかけてみるか。