hirax.net::inside out::2012年04月02日

最新記事(inside out)へ  |   年と月を指定して記事を読む(クリック!)

2012年3月 を読む << 2012年4月 を読む >> 2012年5月 を読む

2012-04-02[n年前へ]

「ウォーリーを探し出す」Mathematicaコードが「してること」 

 「Mathematicaでウォーリーを探せ!」("How do I find Waldo with Mathematica?")が面白かったので、Mathematicaのコードが何をしているかを眺めてみました。

 まずは、Mathematicaコードに簡単な注釈を書き加えてみました。それが下のラクガキです(エッジ検出のテンプレートを間違って4x5で描いてしまいました。正しくは4x4です)。

 このMathematicaコードは、次のような処理を行います。ウォーリーを見つけるために用いられているのは、「(赤色に対する)横エッジ検出」です。

  1. 所定のURLから現画像(waldo)を読み込む(Import)
  2. 現画像(waldo)をRGBそれぞれの画像として分解
  3. RGB画像から(R-G-B)という演算を行い、赤色の量を示す赤画像(マトリクス)を作成
  4. 横(水平)エッジ検出用テンプレート(4x4)を作成。テンプレートは上半分=1、下半分=0
  5. 赤画像の各領域と横(水平)エッジ検出用テンプレート間で”相関”(実際にはベクトル間距離)を算出
  6. ”相関”画像を閾値をもとに2値化
  7. ”相関”画像は実際には”距離”を使っているので、「値が小さい方がマッチしている」ので、値を反転(ColorNegate)
  8. 膨張処理用に円形のカーネルを作成(DiskMatrix)
  9. 2値化された(マッチするほど値が大きい)”相関”画像を円形カーネルを使って膨張処理(Dilation)
  10. 非マッチ部は0.5・マッチ部は1.0にサチらせたマスク画像作成(ImageAdd部)
  11. 原画像(waldo)とマスク画像を乗算し、完成!

 ウォーリーを見つけ出すために使われた③④⑤あたりの「(赤色に対する)横エッジ検出」処理が、シンプルだけれどもなかなか上手く動いているようで、とても面白く感じられます。エッジ検出用のテンプレートのサイズも、4x4という大きさは「必要十分」で上手い…と感心させられます。

 ところで、このMathematicaコードでは、「赤白の横線部があると、ウォリーでなくともマッチしてしまう」でしょう。もしも、より確実にウォーリーだけを見つけ出そうとしたら、一体どんなコードを書けば良いのでしょうか?(この続きが『「ウォーリーを探す出す」多重解像度解析コードを書いてみる!?』です)

「ウォーリーを探し出す」Mathematicaコードが「してること」「ウォーリーを探し出す」Mathematicaコードが「してること」