顔の分解 (1)

顔エリアの推測は大体できているので、あとは眼を分解できれば、入力画像から眼を切り出して、comitionのような作者を特定とか*1、自動的にメガネをつける謎のツールとか、特徴として判定に使ったりとか夢が広がるのでやったぜな感じなのですが、どうやって分解するか悩んでいます。
ここに書いている間もぐるぐる。
大まかには、

  1. 肌とそれ以外を分離
  2. 肌の中にある大きさ上位2、3のエリアは眼と口なので、口がありそうなときはY座標から口を推測して除外する
  3. 四角形に近似した矩形を眼のエリアとする
  4. 完!
  5. 二つの眼エリアの座標と比から顔のゆがみを推測して、アフィン変換で正面に戻す
  6. 続く

でいいと思うのですが、1と2ですでに微妙で、いまのところ、

  1. HSVチャンネルごとのヒストグラムを作って最も使われている色相+彩度+明度を取得→肌の色であると推測
  2. その周辺色を閾値に2値化
  3. 肌とその他の分離完了!
  4. X軸、Y軸での肌の割合の変位から眼の位置を推測する(眼の位置は肌の割合が急激に減少して眼を過ぎた後に急激に増加する。先にY軸方向で範囲を狭めて、X軸は顔の量隅と眉間の両隅で切る。回転もあるため45°〜-45°で試して尤もらしい角度(=眼の領域が一番狭い角度)を選択する)

f:id:ultraist:20080414095212p:image
とかで、やってみているのですが、1の時点で、推測した顔エリア内に髪が多いと(B)、そっち側で分離されてしまうので、上下を切りたいのですが、そうすると斜めを向いている場合に眼が切れることがあるので、どのくらいで切るべきかとか、切らずに別の方法を考えるべきかとか。リアル人間の処理のように肌色検出して分けると、肌が緑だったり、髪がオレンジだったときにうまく分離できない。4の方法はこれが最適なのかもっといい方法があるかとか。肌と髪とそれ以外の3つに分離できれば閉鎖領域でラベリングして抽出できるのではとか(背景色と髪の割合がまた問題になるので、Y座標で判定?)、位置と密度できれいにクラスタ分割できないかとか。いっそ黒っぽい色でとってしまうとか(眼に色が入っていると取れない)。眼は縦横比の違いなども含め作風によって変化が激しいのでテンプレート的な方法が使えない。
うー、画像処理のこういうときああするテーブルを持ってないのがダメなのは分かっているので、基礎とか一応勉強しているのですが、まだ基礎の基礎過ぎて、つい思いつくままコーディングしてしまう。
今週中には、やりたい。こんなの簡単だと思っていたんですけど、捨てきれない例外が多い……。

*1:できるのか知らない