マギ(36)
- 作者: 大高忍
- 出版社/メーカー: 小学館
- 発売日: 2017/11/02
- メディア: Kindle版
- この商品を含むブログを見る
急な展開やな。
シンドバットの心変わりは凄い。
本当に頭が良いな。
ルフを書き換えたせいで凄い苦労する事になっていますね。
ルフに還す天使みたいヤツの造形が邪悪っぽくて、パッと見て神聖化する気にはなれないなぁ。
人々は喜んで近寄っていってるけど普通はなんだあれってなりそうですね。
ルフに還す天使ってモブキャラなので、その相手に苦労している主人公チームに違和感を覚えますね。
アリババが王の器に覚醒しましたが辛い状況が続きますね。
対話なく宣戦布告してくるあたり展開が急です。
世界を敵にまわしても意志を貫くってのは辛い事ですね。
展開として、別世界との対話をどう描くのか気になっていましたが、ダビデが出てきて、ちょっと残念かな。
次巻で完結みたいですね。
楽しみです。
JavaCV を使用して 三国志大戦4 解任済み武将カード の 武将 を判定する
前回は難しい事をして失敗したので、今回は単純にテンプレート画像を縮小してマッチングしてみる。
以下、テンプレート画像のリサイズをしてマッチングしている。
public class TemplateMatching { private static final float SIKITI = 0.95f; public static void main(String[] args) { List<Mat> images = Arrays.asList( imread("{武将カードリスト画像}"), imread("{武将カードリスト画像}"), imread("{武将カードリスト画像}")); Mat template = imread("{テンプレート画像}", CV_LOAD_IMAGE_GRAYSCALE); // サイズ調整 resize(template, template, new Size(40, 64), 0, 0, INTER_AREA); for (Mat image : images) { Mat grey = new Mat(image.size(), CV_8UC1); cvtColor(image, grey, COLOR_BGR2GRAY); Size size = new Size(grey.cols() - template.cols() + 1, grey.rows() - template.rows() + 1); Mat result = new Mat(size, CV_32FC1); matchTemplate(grey, template, result, TM_CCORR_NORMED); getPointsFromMatAboveThreshold(result, SIKITI).stream().forEach((point) -> { rectangle(image, new Rect(point.x(), point.y(), template.cols(), template.rows()), Scalar.RED, 2, 0, 0); }); imshow("Result", image); waitKey(0); } destroyAllWindows(); } public static List<Point> getPointsFromMatAboveThreshold(Mat m, float t) { List<Point> matches = new ArrayList<>(); FloatIndexer indexer = m.createIndexer(); for (int y = 0; y < m.rows(); y++) { for (int x = 0; x < m.cols(); x++) { if (indexer.get(y, x) > t) { System.out.println("(" + x + "," + y + ") = " + indexer.get(y, x)); matches.add(new Point(x, y)); } } } return matches; } }
リサイズは 横40 縦64 としている。
この数値は 三国志大戦.NET から参照している。
以下、実行結果。
いい感じに判定されている!
画像を縮小させる事は大事ですね。
ただ比較対象の画像サイズによっては 横40 縦64 でもうまく判定されないものがあります。
機器によって画面サイズが違うのでズレが生じるのかな。
より精度を上げるには比較する画像から武将カードのサイズを取得して、それに合わせてテンプレート画像をリサイズする必要がありますね。
うーん、どんどん深い所へと行っていますね。
肝となる部分なので後回しにしても痛い目を見そうだ。
どうしようかな。
JavaCV を使用して 三国志大戦4 解任済み武将カード の 武将 を 特徴点 から判定する(失敗)
前回、リストから1単位の武将データを抽出する事ができた。
今回、そこから武将を判定したい。
テキストである武将名は読み取りが難しいうえに、蜀の劉備、漢の劉備、レアリティが違う劉備、性能が一緒だけど絵柄が劉備など違うパターンがありぎすて正解を得るのに考慮する事が多すぎる。
絵柄は重複する事がないので、絵柄から武将を判定する。
テンプレートマッチングでやってみても、うまく判定されない。
どうやら画像サイズが違うと判定されないみたいね。
色々調べてみると特徴点でマッチングする手法を知りました。
以下、色んなサイトを見て作成。
public class PointMatching { public static void main(String[] args) { Mat mat1 = imread("{1単位の武将データの画像}"); Mat mat2 = imread("{武将の画像}"); // 特徴点抽出 KeyPointVector keyPointVector1 = new KeyPointVector(); KeyPointVector keyPointVector2 = new KeyPointVector(); ORB orb = ORB.create(); orb.detect(mat1, keyPointVector1); orb.detect(mat2, keyPointVector2); // 特徴記述 Mat matDescriptor1 = new Mat(); Mat matDescriptor2 = new Mat(); orb.compute(mat1, keyPointVector1, matDescriptor1); orb.compute(mat2, keyPointVector2, matDescriptor2); // 特徴点マッチング DMatchVector vector = new DMatchVector(); DescriptorMatcher matcher = DescriptorMatcher.create("BruteForce-Hamming"); matcher.match(matDescriptor1, matDescriptor2, vector); // 結果作成 Mat result = new Mat(); drawMatches(mat1, keyPointVector1, mat2, keyPointVector2, vector, result); imshow("Resutl", result); waitKey(0); destroyAllWindows(); } }
以下、実行結果です。
左の画像と右の画像の 特徴点 を線でつなげています。
うーん、ぜんぜんダメやん。
しきい値を設定して 特徴点 を選別しても大して変わりません。
大きい画像を用意しておけば空気を読んでマッチングしてくれるやろっと甘い考えでした。
特徴点マッチングの難しい所は特徴点がどこまで一致していたら同じと判定するかですね。
うーん、向いていない事をやっている感があります。
これなら大きめの画像を用意しておいて、比較する画像に合わせて縮小させてパターンマッチングするほうが楽で正確でしょうね。
比較しあう画像を同サイズにするって、パターンマッチングにおいては最適化しているといえますね。
一見、画像を縮小すると情報が抜け落ちている感覚ですが、不要な情報を削っているといえるのかな。
次はテンプレートとなる大きめの武将カードを用意しておいて、リストから抽出した1単位の画像サイズに合わせて縮小処理をしてパターンマッチングしてみるだな。
JavaCV を使用して 三国志大戦4 解任済み武将カード の1単位を判定する
こちらの続きとして 解任済み武将カード のリストから1単位を判定したい。
リストから1単位を判定できれば、あとは抽出して個別処理を行うだけになる。
最初は枠を判定して、そこからゴリゴリと座標計算して~みたいな事になるのかなぁと考えていた。
OpenCV ができる事を見ていると 輪郭検出 というワードがあり、調べてみると要件に非常に合っていたので、こちらで行う事にした。
キッカケとなったのは以下のサイト。
AVFoundation+OpenCVで矩形検出(「名刺撮影用カメラ」みたいなやつ作ってみました) | Developers.IO
サイトでは名刺を判定している。
これを 武将カード1単位 に置き換えできると思った。
画像処理に関しては右も左もわからないですが、処理に対して1つ1つ解説があって非常に助かりました。
感謝しかありません。
以下のサイトも非常に参考になった。
全体と各工程が非常にわかりやすく解説されている。
処理をする意図がわかると理解が進むので助かります。
サイトの処理を参考にしつつ以下を作成して実行。
public class FindContours { public static void main(String[] args) { // 画像を読込 Mat mat = imread("{画像パス}"); // グレースケール化 Mat gray = new Mat(mat.size(), CV_8UC1); cvtColor(mat, gray, COLOR_BGR2GRAY); // しきい値処理 threshold(gray, gray, 0, 255, CV_THRESH_OTSU); // 輪郭検出 MatVector contours = new MatVector(); Mat hierarchy = new Mat(); findContours(gray, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_TC89_L1); List<Mat> mats = new ArrayList<>(); int max_level = 0; for (int i = 0; i < contours.size(); i++) { // ある程度の面積が有るものだけに絞る double area = contourArea(contours.get(i), false); if (area > 15000) { //輪郭を直線近似する Mat approx = new Mat(); approxPolyDP(contours.get(i), approx, 0.01 * arcLength(contours.get(i), true), true); // 矩形のみ取得 if (approx.size().area() == 4) { // 1単位を収集 Rect rect = boundingRect(approx); mats.add(new Mat(mat, rect)); // 輪郭を塗る drawContours(mat, contours, i, Scalar.RED, 2, CV_AA, hierarchy, max_level, new Point()); } } } imshow("Result", mat); waitKey(0); destroyAllWindows(); } }
以下、実行結果。
素晴らしい!
1単位を判定しライン赤色でカッコっています。
1単位は見えた、あとはそこを抽出するだけだ。
できた。
素晴らしい!
ただ課題もある。
以下は見切れているパターン。
これに関しては諦めるかも。
個別処理用に特殊な事をする事になりそう。
対応するコストが高い気がしている。
以下はヘッダが判定されている。
輪郭検出なので処理結果としては正しいんだけど 武将カード ではないので除外する必要がある。
ろ過作業みたいな事をしないといけない。
不要な情報の除去って輪郭検出の前と後、どちらでやるんだろうか。
状況にもよるんだろうけど、ここも考えていかないといけないね。
Ver.1.1.0B バージョンアップ
久しぶりに三国志大戦のみの記事を書くなぁ。
象兵の追加と 南蛮王の大号令 がまさかの上方修正でテンションあがって象兵デッキで全国に行っている。
以下デッキの感想。
SR 孟獲
かなり好きなカード。
前作は回転率が凄かったですが、今回はバランス型って感じなのかな。
総合的な性能は上がっているんじゃないかな。
作家が 風間雷太先生 なので下手に武力下げられない圧力を感じる。
将器復活(6秒)と特技復活(5秒)で復活カウントが 11秒 マイナスされる。
復活までにかかる秒数 30 - 11 = 19秒
1カウント は 2.5秒 なので 8カウントぐらいで復活できる。
ピッタリはないから撤退したら 9カウント ぐらいで帰ってくるって覚えておこうかな。
通常だと撤退したら復活するまで 12カウント なので 3-4カウント ほど早く帰ってくる。
副将器も揃えたら 5カウント ぐらい差がつきそう。
SR 祝融
姉御って感じで良いですね。
スペックが非常に高い。
計略は基本的に使うつもりはない。
状況によるけど祝融の計略を使うぐらいなら士気2貯まるまで耐えて 南蛮王の大号令 をやったほうがリターンがでかいと思う。
相当苦しい時に守りで使う事を想定している。
デッキの生命線だと思っていて一番丁寧に使っている。
R 孟優
こっちは 10カウント ほどで帰ってくる。
将器復活(6秒)で 再起の法 が復活までの秒を 24秒 減少なので撤退して即 再起の法 を叩いてもすぐに帰ってくるの良いね。
はじき戦法は、はじくより攻城とるために使う事が多いなぁ。
SR 鄒氏
必須カード。
とりあえず入れとけ。