@m_seki の

I like ruby tooから引っ越し

ポケカのカードブロックが変更になるとのこと

ポケカのカードブロックが変更になり[A]のカードがレギュ落ちするぞ

www.pokemon-card.com

それはいいけど[A]のカードっていうのはどれなのさ!(公式サイトではまだそういう単位の検索ができないのだ)

どうする?

しょうがない。画像処理を使って、[A][B][C]を判定するのを作ろう!

GitHub - seki/pcg_abcd: Pokemon Card Game card block classifier

機械学習が流行っているので、それは使わずOpenCVのテンプレートマッチで実装することにしよう。

準備(追記)

パッケージ化する前に試したこと。

OpenCVのテンプレートマッチの誤差を比較して一番確からしいものを選ぶ作戦。

  1. カードの画像から[A][B][C]を切り出して正規化(色とかサイズとか)したものをテンプレートにする。(github見てね)
  2. 指定されたURLから画像をカードのダウンロードして、三種類のテンプレートとマッチさせる。
  3. 実験してみたところ、どのテンプレートもカードの同じ場所とマッチするが、スコア(デフォルトのアルゴリズムでは小さい方がより似ている)は正解のテンプレートと正解でないものの差がとても大きいこと確かめた。
  4. スコア順にソートして最小のものを採用することとする。
  5. なお、XYなどのマークのないカードはスコアがとても大きいので、大きすぎるものは例外とすることにした。
私の環境の問題...

OpenCVのテンプレートマッチを使えばできそう!
でもmacOSOpenCVのgem作るのめんどくさい...そういえばば前にそういうDockerイメージを作ってたぞ。なんという幸運。

https://cloud.docker.com/repository/docker/mseki/ruby-opencv

そういう問題がない人は...普通にRubyとGemでやればできるぞ。出来上がったのはこれ。

require 'opencv'
require 'drb'
require 'open-uri'

class ABCandD
  def initialize
    @template = %w(A B C).map {|a| [a, OpenCV::IplImage.load("/data/#{a}.png")]}
  end

  def zap(uri)
    img = load_img(uri)
    result = @template.map { |pair|
      [img.match_template(pair[1]).min_max_loc[0], pair[0]]
    }.sort_by {|ary| ary.first}
    result[0]
  end

  def classify(uri)
    score, klass = zap(uri)
    raise "Error too large #{score}" if score > 5000000.0
    klass
  end

  def load_img(uri)
    data = URI.open(uri).read
    OpenCV::IplImage.decode(data)
  end
end

if __FILE__ == $0
  if uri = ARGV.shift
    DRb.start_service(uri, ABCandD.new)
    DRb.thread.join
  end
end

Dockerの場合はビルドしてから実行。

$ docker build -t mseki/pcg-abcd:0.1 .
$ docker run -p 50151:50151 mseki/pcg-abcd:0.1

ポート番号の50151はdRubyのサービスのポートだよ。

別の端末からirbなどで質問すれば答えてくれる。カードの画像のURLを渡そう。

$ irb -r drb
irb(main):001:0> sorter = DRbObject.new_with_uri 'druby://localhost:50151'
irb(main):002:0> sorter.classify "https://www.pokemon-card.com/assets/images/card_images/large/SM12/037304_P_REKKUUZAGX.jpg"
=> "B"
サンムーン世代のトレーナーズのカードブロック一覧だよ

手持ちのメモ(mysqlにメモしてある。もしかしたら抜けがあるかも)にあったトレーナーズを判定させてみた。

irb(main):038:0> pp it; nil
[["あなぬけのヒモ", "グッズ", "A"],
 ["いちゃもんスプレー", "グッズ", "A"],
 ["おおきいマラサダ", "グッズ", "A"],
 ["きずぐすり", "グッズ", "A"],
 ["のぞきみレッドカード", "グッズ", "A"],
 ["ふしぎなアメ", "グッズ", "A"],
 ["まんたんのくすり", "グッズ", "A"],
 ["むしよけスプレー", "グッズ", "A"],
 ["アクアパッチ", "グッズ", "A"],
 ["エネくじ", "グッズ", "A"],
 ["エネルギーつけかえ", "グッズ", "A"],
 ["エネルギーリサイクル", "グッズ", "A"],
 ["エネルギー回収", "グッズ", "A"],
 ["カウンターキャッチャー", "グッズ", "A"],
 ["クラッシュハンマー", "グッズ", "A"],
 ["スーパーボール", "グッズ", "A"],
 ["スーパーポケモン回収", "グッズ", "A"],
 ["タイマーボール", "グッズ", "A"],
 ["ダメージムーバー", "グッズ", "A"],
 ["ネストボール", "グッズ", "A"],
 ["ハイパーボール", "グッズ", "A"],
 ["フィールドブロアー", "グッズ", "A"],
 ["ポケモンいれかえ", "グッズ", "A"],
 ["ポケモンキャッチャー", "グッズ", "A"],
 ["マルチつけかえ", "グッズ", "A"],
 ["モンスターボール", "グッズ", "A"],
 ["レスキュータンカ", "グッズ", "A"],
 ["ロトム図鑑", "グッズ", "A"],
 ["ロトム図鑑 ポケファインダーモード", "グッズ", "A"],
 ["勝利の勲章", "グッズ", "A"],
 ["改造ハンマー", "グッズ", "A"],
 ["殿堂の書", "グッズ", "A"],
 ["やまおとこ", "サポート", "A"],
 ["アセロラ", "サポート", "A"],
 ["イリマ", "サポート", "A"],
 ["カキ", "サポート", "A"],
 ["ククイ博士", "サポート", "A"],
 ["グズマ", "サポート", "A"],
 ["グラジオ", "サポート", "A"],
 ["サトシのゆうじょう", "サポート", "A"],
 ["スイレン", "サポート", "A"],
 ["スカル団のしたっぱ", "サポート", "A"],
 ["ハウ", "サポート", "A"],
 ["ハラ", "サポート", "A"],
 ["ビッケ", "サポート", "A"],
 ["プルメリ", "サポート", "A"],
 ["ポケモンブリーダー", "サポート", "A"],
 ["マオ", "サポート", "A"],
 ["マーマネ", "サポート", "A"],
 ["ライチ", "サポート", "A"],
 ["リーリエ", "サポート", "A"],
 ["ルザミーネ", "サポート", "A"],
 ["ロイヤルマスク", "サポート", "A"],
 ["ロケット団のいやがらせ", "サポート", "A"],
 ["せせらぎの丘", "スタジアム", "A"],
 ["エーテルパラダイス保護区", "スタジアム", "A"],
 ["チャンピオンズフェスティバル", "スタジアム", "A"],
 ["ポータウン", "スタジアム", "A"],
 ["ラナキラマウンテン", "スタジアム", "A"],
 ["喰いつくされた原野", "スタジアム", "A"],
 ["日輪の祭壇", "スタジアム", "A"],
 ["月輪の祭壇", "スタジアム", "A"],
 ["虚ろの海", "スタジアム", "A"],
 ["こだわりハチマキ", "ポケモンのどうぐ", "A"],
 ["じゃくてんほけん", "ポケモンのどうぐ", "A"],
 ["どくバリ", "ポケモンのどうぐ", "A"],
 ["ねがいのバトン", "ポケモンのどうぐ", "A"],
 ["エレクトロメモリ", "ポケモンのどうぐ", "A"],
 ["サイキックメモリ", "ポケモンのどうぐ", "A"],
 ["ダッシュポーチ", "ポケモンのどうぐ", "A"],
 ["ファイトメモリ", "ポケモンのどうぐ", "A"],
 ["ファイヤーメモリ", "ポケモンのどうぐ", "A"],
 ["ムキムキダンベル", "ポケモンのどうぐ", "A"],
 ["古代のクリスタル", "ポケモンのどうぐ", "A"],
 ["学習装置", "ポケモンのどうぐ", "A"],
 ["あとだしハンマー", "グッズ", "B"],
 ["いれかえフロート", "グッズ", "B"],
 ["おとりよせパッド", "グッズ", "B"],
 ["ともだちてちょう", "グッズ", "B"],
 ["ふっかつそう", "グッズ", "B"],
 ["ぼうけんのカバン", "グッズ", "B"],
 ["ウルトラボール", "グッズ", "B"],
 ["エスケープボード", "グッズ", "B"],
 ["エネポーター", "グッズ", "B"],
 ["エネルギースピナー", "グッズ", "B"],
 ["エネルギー循環装置", "グッズ", "B"],
 ["エレキチャージャー", "グッズ", "B"],
 ["エレキパワー", "グッズ", "B"],
 ["カスタムキャッチャー", "グッズ", "B"],
 ["ギリギリポーション", "グッズ", "B"],
 ["ダートじてんしゃ", "グッズ", "B"],
 ["デンジャラスドリル", "グッズ", "B"],
 ["ネットボール", "グッズ", "B"],
 ["ハンサムホイッスル", "グッズ", "B"],
 ["ビーストリング", "グッズ", "B"],
 ["フレンドボール", "グッズ", "B"],
 ["ポケナビ", "グッズ", "B"],
 ["ミステリートレジャー", "グッズ", "B"],
 ["ミックスハーブ", "グッズ", "B"],
 ["ミッシングクローバー", "グッズ", "B"],
 ["モーモーミルク", "グッズ", "B"],
 ["リターンラベル", "グッズ", "B"],
 ["ルアーボール", "グッズ", "B"],
 ["レインボーブラシ", "グッズ", "B"],
 ["ロストミキサー", "グッズ", "B"],
 ["化石発掘マップ", "グッズ", "B"],
 ["火打石", "グッズ", "B"],
 ["TVレポーター", "サポート", "B"],
 ["おじょうさま", "サポート", "B"],
 ["かんこうきゃく", "サポート", "B"],
 ["ぼんぐり職人", "サポート", "B"],
 ["アカギ", "サポート", "B"],
 ["アカネ", "サポート", "B"],
 ["ウツギ博士のレクチャー", "サポート", "B"],
 ["ウルトラ調査隊", "サポート", "B"],
 ["エーテル財団職員", "サポート", "B"],
 ["カツラの一発勝負", "サポート", "B"],
 ["カヒリ", "サポート", "B"],
 ["カルネ", "サポート", "B"],
 ["クチナシ", "サポート", "B"],
 ["ザオボー", "サポート", "B"],
 ["シロナ", "サポート", "B"],
 ["ジャッジマン", "サポート", "B"],
 ["ダイゴの決断", "サポート", "B"],
 ["デンジ", "サポート", "B"],
 ["ナタネ", "サポート", "B"],
 ["ナリヤ・オーキド", "サポート", "B"],
 ["ノボリとクダリ", "サポート", "B"],
 ["ハンサム", "サポート", "B"],
 ["ヒガナ", "サポート", "B"],
 ["フウとラン", "サポート", "B"],
 ["フラダリ", "サポート", "B"],
 ["ポケモンだいすきクラブ", "サポート", "B"],
 ["マキシ", "サポート", "B"],
 ["マサキのメンテナンス", "サポート", "B"],
 ["マツバ", "サポート", "B"],
 ["マツリカ", "サポート", "B"],
 ["マーズ", "サポート", "B"],
 ["ミカン", "サポート", "B"],
 ["モノマネむすめ", "サポート", "B"],
 ["ユリーカ", "サポート", "B"],
 ["ラジュルネ", "サポート", "B"],
 ["ラニュイ", "サポート", "B"],
 ["ルザミーネ", "サポート", "B"],
 ["ルスワール", "サポート", "B"],
 ["ルチア", "サポート", "B"],
 ["ルミタン", "サポート", "B"],
 ["ワタル", "サポート", "B"],
 ["地底探険隊", "サポート", "B"],
 ["釣り人", "サポート", "B"],
 ["そらのはしら", "スタジアム", "B"],
 ["ウルトラスペース", "スタジアム", "B"],
 ["サンダーマウンテン", "スタジアム", "B"],
 ["テンガン山", "スタジアム", "B"],
 ["ヒートファクトリー", "スタジアム", "B"],
 ["フラダリラボ", "スタジアム", "B"],
 ["ブラックマーケット", "スタジアム", "B"],
 ["プレイヤーズセレモニー", "スタジアム", "B"],
 ["ライフフォレスト", "スタジアム", "B"],
 ["ワンダーラビリンス", "スタジアム", "B"],
 ["ヴェラ火山公園", "スタジアム", "B"],
 ["戒めの祠", "スタジアム", "B"],
 ["こだわりメット", "ポケモンのどうぐ", "B"],
 ["のろいのおふだ", "ポケモンのどうぐ", "B"],
 ["ウォーターメモリ", "ポケモンのどうぐ", "B"],
 ["エスケープボード", "ポケモンのどうぐ", "B"],
 ["カウンターゲイン", "ポケモンのどうぐ", "B"],
 ["グラスメモリ", "ポケモンのどうぐ", "B"],
 ["ハッスルベルト", "ポケモンのどうぐ", "B"],
 ["フェアリーチャーム UB", "ポケモンのどうぐ", "B"],
 ["フェアリーチャームドラゴン", "ポケモンのどうぐ", "B"],
 ["フェアリーチャーム草", "ポケモンのどうぐ", "B"],
 ["フェアリーチャーム超", "ポケモンのどうぐ", "B"],
 ["フェアリーチャーム闘", "ポケモンのどうぐ", "B"],
 ["メタルゴーグル", "ポケモンのどうぐ", "B"],
 ["竜の鉤爪", "ポケモンのどうぐ", "B"],
 ["鋼鉄のフライパン", "ポケモンのどうぐ", "B"],
 ["びっくりボックス", "グッズ", "C"],
 ["やみのいし", "グッズ", "C"],
 ["グレートキャッチャー", "グッズ", "C"],
 ["グレートポーション", "グッズ", "C"],
 ["ザクザクピッケル", "グッズ", "C"],
 ["ジャッジマンホイッスル", "グッズ", "C"],
 ["スイレンのつりざお", "グッズ", "C"],
 ["スタジアムナビ", "グッズ", "C"],
 ["タッグコール", "グッズ", "C"],
 ["タッグスイッチ", "グッズ", "C"],
 ["プレシャスボール", "グッズ", "C"],
 ["ポケギア3.0", "グッズ", "C"],
 ["ポケモン通信", "グッズ", "C"],
 ["リセットスタンプ", "グッズ", "C"],
 ["炎の結晶", "グッズ", "C"],
 ["退化スプレーZ", "グッズ", "C"],
 ["電磁レーダー", "グッズ", "C"],
 ["Nの覚悟", "サポート", "C"],
 ["あばれる君", "サポート", "C"],
 ["かいじゅうマニア", "サポート", "C"],
 ["きとうし", "サポート", "C"],
 ["むしとりしょうねん", "サポート", "C"],
 ["アローラの仲間たち", "サポート", "C"],
 ["アンズ", "サポート", "C"],
 ["イツキ", "サポート", "C"],
 ["ウルトラフォレストのかみつかい", "サポート", "C"],
 ["エリカ", "サポート", "C"],
 ["エリカのおもてなし", "サポート", "C"],
 ["オーキド博士のセッティング", "サポート", "C"],
 ["カスミ&カンナ", "サポート", "C"],
 ["カスミのおねがい", "サポート", "C"],
 ["カスミのやる気", "サポート", "C"],
 ["カスミの水さばき", "サポート", "C"],
 ["カツラのクイズショー", "サポート", "C"],
 ["キョウの罠", "サポート", "C"],
 ["ギーマ", "サポート", "C"],
 ["グズマ&ハラ", "サポート", "C"],
 ["グリーンの戦略", "サポート", "C"],
 ["コーチトレーナー", "サポート", "C"],
 ["サカキの追放", "サポート", "C"],
 ["シロナ&カトレア", "サポート", "C"],
 ["ジュジュベ&ハチクマン", "サポート", "C"],
 ["タケシのガッツ", "サポート", "C"],
 ["タケシのトレーニング", "サポート", "C"],
 ["ナツメの暗示", "サポート", "C"],
 ["ハプウ", "サポート", "C"],
 ["ブルーの探索", "サポート", "C"],
 ["ホミカ", "サポート", "C"],
 ["ポケモンセンターのお姉さん", "サポート", "C"],
 ["マオ&スイレン", "サポート", "C"],
 ["マサキの解析", "サポート", "C"],
 ["マチスの作戦", "サポート", "C"],
 ["マーレイン", "サポート", "C"],
 ["ムサシとコジロウ", "サポート", "C"],
 ["メイ", "サポート", "C"],
 ["ヤーコン", "サポート", "C"],
 ["リーリエの全力", "サポート", "C"],
 ["レッド&グリーン", "サポート", "C"],
 ["レッドの挑戦", "サポート", "C"],
 ["ローラースケーター", "サポート", "C"],
 ["溶接工", "サポート", "C"],
 ["まどろみの森", "スタジアム", "C"],
 ["カスミのハナダシティジム", "スタジアム", "C"],
 ["シオンタウン", "スタジアム", "C"],
 ["タケシのニビシティジム", "スタジアム", "C"],
 ["ダストアイランド", "スタジアム", "C"],
 ["チャンピオンズフェスティバル", "スタジアム", "C"],
 ["トキワの森", "スタジアム", "C"],
 ["ナイトシティ", "スタジアム", "C"],
 ["ブリザードタウン", "スタジアム", "C"],
 ["ポケモンけんきゅうじょ", "スタジアム", "C"],
 ["巨大なカマド", "スタジアム", "C"],
 ["格闘道場", "スタジアム", "C"],
 ["混沌のうねり", "スタジアム", "C"],
 ["無人発電所", "スタジアム", "C"],
 ["Uターンボード", "ポケモンのどうぐ", "C"],
 ["くろおび", "ポケモンのどうぐ", "C"],
 ["しまめぐりのあかし", "ポケモンのどうぐ", "C"],
 ["にじいろのはな", "ポケモンのどうぐ", "C"],
 ["みみなりベル", "ポケモンのどうぐ", "C"],
 ["ジャイアントボム", "ポケモンのどうぐ", "C"],
 ["ドラゴンZ ドラゴンクロー", "ポケモンのどうぐ", "C"],
 ["ノーマルZ たいあたり", "ポケモンのどうぐ", "C"],
 ["ヒコウZ エアスラッシュ", "ポケモンのどうぐ", "C"],
 ["ビーストナイト", "ポケモンのどうぐ", "C"],
 ["ビーストブリンガー", "ポケモンのどうぐ", "C"],
 ["フェアリーチャーム 特性", "ポケモンのどうぐ", "C"],
 ["フェアリーチャーム 雷", "ポケモンのどうぐ", "C"],
 ["ムキムキパッド", "ポケモンのどうぐ", "C"],
 ["メタルコアバリア", "ポケモンのどうぐ", "C"],
 ["隠密フード", "ポケモンのどうぐ", "C"]]
あわせて買いたい