OpenCVでスプラトゥーン2の試合中の情報を解析するツールを作っている3

前回 http://blog.jiikko.com/148

ツール開発日記です。
今日実装したことを書いていこうと思う。

テストを書いているため、テストの入力に使う画像ファイルを大量に保存している。大量に保存しているので、同じ画像を入力にした意味の無いテストがいくつかあったので、それを検出できるようにしてみた。画像ファイルのハッシュ値をとって、重複した画像でテストしている場合にテストが落ちるようになった。便利。

  class DuplicatingImageDetector
    cattr_accessor :table, default: {}
    def self.duplicated?(image_path)
      digest = Digest::MD5.hexdigest(File.read(image_path))
      if(key = table[digest])
        raise "#{image_path}は、すでに別のexampleで参照されました。#{key}でかぶっています。"
      else
        table[digest] = image_path
      end
    end
  end

https://qiita.com/Kazuma_Kikuya/items/4767afe581c94b0c16f1
今作っているツールは元記事にあった理論で検出をしている。一部のフレームは落とすけどだいたいのケースはうまくいく。でも、まったく適用できないケースを見つけてしまった。

具体的に書くと、「黒い線」の上にある「ブキアイコン」は、「黒い線」と色が遠いので2値化を経て識別できているんだけど、「黒い線」に近い暗いの色ブキアイコンが存在していて、2値化では識別できなかったのだ。
完全に詰みっぽいんだけど、苦肉の策で暗い色のブキアイコンを別途用意して、マーキングするという前処理を入れることにした。これで検出できるようになった。

https://github.com/hasegaw/IkaLog でブキの判定処理が苦労したって記事を昔に読んだことがあって、それをふと思い出した。


今までは、同じ前処理で判定ができていたんだけど、判定ができない画面を見つけた。調べると、「特定の状況下の画面」では精度を上げるために入れた、前処理が逆効果になっていることがわかった。
判定に失敗したら、問題の前処理をskipして再実行するようにしたらうまくいった。組合せ爆発だ。


全体がだいぶ継ぎ足しの実装だったので、リファクタリングをちょっとした。
進め方は、長いメソッドをActiveSupportのcallbackへ移動していく、ということをした。この過程でこのクラスに依存する意味ないですね、みたいなことを続々でてきた。これらを行うことで凝集性と結合性がよくなったきがする。まだ途中なので継続してやっていきたい。