機械学習を使ってApexのプレイ動画から武器使用率を算出する

最終的な目標はプレイスタイルの解析 近年、動画投稿・配信サービスの普及により、ゲーム実況というものがエンタメの1カテゴリとして確立してきていると思う。感染症流行の影響が大きいと思うが、2021年1月~3月の主要ゲーム配信サイト(Twitch、YouTube Gaming、Facebook Gaming)の合計視聴時間が前年同期比で80%増加したというデータもある。1ゲームのジャンルとしてはアクション・RPG・シミュレーションなどあらゆるものが実況の対象になるが、今回はFPSのゲーム実況にスポットを当てる。 FPSの分野では、オンライン対戦システムおよび、いわゆるランクシステムが整備されているものが多くなっている。ランクシステムは、プレイヤーの習熟度のようなものを可視化する。こうしたランクに関する情報は、視聴者にとって、プレイヤーのことをパッと理解するために非常に役立っていると思う。 現状、ランク情報やダメージ数、キルデス比等はゲームシステムから参照できるようになっていることが多いと思う。ただ、個人的にはより細かい、プレイヤーのプレイスタイルのようなものを可視化できる情報があると、プレイヤーについて理解を深めるためのよい材料になると思った。 最終的にはゲームシステムから直接確認出来るデータだけでなく、ゲームプレイ動画の解析結果から、プレイヤーのプレイスタイルをうまく可視化したい。今回は、Apexを題材にし、プレイヤーのプレイスタイルを示す1つの指標として、武器使用率をゲームプレイ動画から解析できないか試す。まあ、こういった情報はわざわざ動画を解析しなくても、ゲームシステム側で実装してもらえれば、より正確で容易にデータが取れるとは思う。 全体の作業の流れ 今回の全体の作業の流れは以下のようになっている。 各作業の内容について説明していく。ただし、ゲームプレイ動画のキャプチャ作業については特に説明することがないので、何も説明しない。 武器名表示領域の切り取り データセットを整備するために、ゲーム画面のうち、武器名を表示している領域のみを切り取った画像を作成する必要がある。今回は、動画に対して一定時間ごとのフレームを画像化→特定領域を切り取り→特定の場所に画像ファイルとして保存、という流れでデータセット用の画像を作成した。 一連の画像切り取り作業実施のために、ツールを作成した。GUI部分はPySimpleGUIを利用している。 主に以下を設定できる。 切り取り対象とする動画の保存場所 武器1欄(*1)の画像を保存する場所 武器2欄(*1)の画像を保存する場所 画像を切り抜く領域(*2)(全体サイズに対する割合で指定) (*2)で設定した領域からどれだけずらした画像を何個保存するか 画像切り取り対象とするフレームの時間間隔 (*1)Apexでは、武器を同時に2つ持つことができる。今回は武器1欄と武器2欄を別々のデータセットとして扱う。理由はそちらの方がより精度が上がりそうと思ったためである。 このツールを使えば、ボタンを1回ポチーすることで、後は待っていれば所定の場所に武器名表示領域の画像が保存される。 画像に対して正解ラベルを付ける データセットの正解ラベル付けについて、どのような形式で保存するのが一般的かを私は知らないのだが、今回は各正解ラベル(武器名)ごとに保存フォルダを分けることにした。 以下のように、全武器+“武器なし”(_None)について画像をフォルダ分けした。 この作業にも専用ツールを作成した。 データセットが置かれている場所を指定して、startボタンを押すと、所定の個数づつ未分類の画像が表示される。表示された画像について、正解となる武器名のボタンをポチポチしていき、画像をフォルダ分けする。 ただ、今回データセットの元にしたキャプチャ動画は武器を決まった順番で使うようにしていた。そのため、切り抜かれた画像が最初から決まった武器順で並んでおり、結局このツールはあまり使わなかった。 学習・モデルの保存 データセットの準備が出来たので、ようやく学習をする。学習部分はコードベースで説明する。 まず、データセットの読み込みを行う。かなりコードが汚い。武器名のリストは、以下のコードに含まれていない関数を使ってファイルから読みこんでいる。 Kerasを用いてモデルを生成する関数を作成する。 Optunaを使ってハイパーパラメータを調整しつつ、成績の良いモデルを保存する。(といってもマシンが貧弱で学習に時間がかかるので、5回しか試行を回していない。) 上記のコードを実行したところ、とりあえず今回はテストデータの正解率が99.89%のモデルが出来た。テストデータの推論結果をMatplotlibを使って画像とともに確認してみる。 いい感じに推論できてそうだ。誤答をしたデータについても確認してみる。 今回は2つのデータの推論が間違っていたようだ。上は正答がFlatlineなのに対し、Devotionと推論してしまっており、下は正答がNoneなのに対し、R-301と推論してしまっている。 作成したモデルによるプレイ動画の解析 モデルが出来たので、動画を解析する。解析用のソフトを作成した。 学習用に使ったデータとは別のキャプチャ動画を使って解析したところ、以下のような結果になった。 解析結果を見たところ、大体は合っていると思うが、誤検出されている武器名が末尾に並んでいる。解析結果は正確なものではないため、データの扱いは少し考えないといけない。 最初は自作モデルを作らなくても行けると思っていた 今回、武器使用率算出のために"機械学習のモデルを作成・利用する"という手段を選択した。 この手段を取る前は、TesseractとPyOCRを利用して文字列を認識する方法をとっていた。ただ、認識精度が厳しかったので、利用を断念した。機械学習の勉強にもなると思い、代わりに自作モデルの作成という方法をとった。 今回の識別対象は決まり切った文字列なので、機械学習を使わなくても、より正確な認識方法があるかもしれない。というか、私はApexにあまり詳しくないので、そもそもゲームシステム内で武器使用率を確認できる方法があるかもしれない。 参考にした書籍・動画 機械学習については主にネット上の情報と、以下の書籍の内容を流し読みした程度の理解度である。 ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装 オライリージャパン (2016/9/24) Amazon 楽天市場 また、上記書籍を数年前に読んだときは誤差逆伝播法がいまいち理解できなかった。しかし、Twitterのタイムラインで流れてきた以下の動画が非常に参考になり、とりあえず分かった気にはなれた。出来るだけ条件を簡易にして、高校数学の範囲で説明されている。 まとめ 機械学習を利用してApexのプレイ動画から武器使用率を算出するためのツール群を作成した。解析結果には誤差が含まれるため、利用するためにはまだ工夫をする必要があると思う。 色々試行錯誤をする中で、モデルの性能に最も寄与したのはデータセットの作り方だった。データセットに偏りがあると、それを学習したモデルも偏りのある結果を出力する。データセットの質の重要性を、身をもって実感した。この部分については本記事で書けなかったので、またどこかで記事を書くかもしれない。 Q1 2021 Live Game Streaming Trends - Stream Hatchet ↩︎...

November 1, 2021 · 1 min

顔認識+サーボモーターで顔追従モニターの作成

先日、NT金沢2021というイベントに、リモートで出展参加した。「リモートで出展参加」というのは、具体的に言うと、展示物としてはオンラインで遊べるものをポスターで出展して、私はGoogleMeet(ビデオ会議)をつないでリモートで一部作品の説明をしていた。(関係機材は現地出展した友人に運んでもらった。) GoogleMeetをつなぐには、とりあえずPCが現地(NT金沢の会場)にあれば事足りる。ただせっかくなので、モニターが、話している相手の顔を追跡するようにした。 動作の様子 人の顔に追従するモニタを試作中…。 ■使用素材 画像:いらすとや(https://t.co/H01vPNj6QI) pic.twitter.com/H8fLDuSRjz — 青木晃也 (@aoki_kouya) May 30, 2021 検証時の動画だが、概ね完成形。当日はこのモニターに、GoogleMeetの画面を表示して運用していた。 ハードウェア 使用部品一覧 部品名 備考 JetsonNano開発者キット 顔認識・ビデオ会議・サーボ制御用 Webカメラ×2 1個は顔認識用、1個はビデオ会議用 モニター スピーカーも内蔵 サーボモーター S03T/2BBMG/F×2 強そうなものをチョイス PCA9685モジュール サーボ制御用 サーボやモニタ等を固定するための部品は3Dプリンターで作成した。 WebカメラはとりあえずAmazonで安いものを適当に買った。1種類目はUSB Wi-Fi子機との相性が良くなかったようで、Wi-Fiの接続が不安定になった。2種類目は特に問題なく動いていそうだったので、採用した。ただ、この記事を書いている時点で、採用したWebカメラのAmazonの商品ページはリンク切れになっていた。 ソフトウェア ソフトウェアに関する部分としては、JetsonNano起動後にコンソールで顔追従用プログラムを実行した後、ブラウザ(Chromium)でGoogleMeetを動かしていた。GoogleMeetの方は特に書くことがないため、顔追従用プログラムのソースコード及びセットアップ周りを書いていく。 顔追従用プログラムのソース ソースは以下に置いてある。 顔追従用プログラムのセットアップ周り 上記のソースを動かすには、関係ライブラリをインストールする必要がある。 PCA9685用ライブラリのインストール サーボ制御モジュールPCA9685をPythonから制御するためのPythonパッケージをインストールする。まず以下のコマンドでpip3をインストールする。 sudo apt-get install python3-pip 参考元: NVIDIA Jetson Nano 開発者キットに TensorFlow をインストールする - Qiita...

July 23, 2021 · 1 min

html要素の背景色が変化するアニメーションをCSSで(無理やり)実装する

CSSによるアニメーションについて CSSではanimationプロパティを利用することによって、JavaScriptを使うことなく、HTML要素にアニメーションを付与することができる。 CSSアニメーションの概要は以下の記事を参考にさせていただいた。 今回作りたいもの 今回、以下のような流れでアニメーションする要素を作りたい。 要素の左端から背景色がだんだん元々の背景色Aから色B変わっていき、背景全体が色Bになる。この時、色Aと色Bの境界はグラデーションにする。 背景全体が色Bのまましばらく維持する。 要素の左端から背景色がだんだん色Bから色Aに変わっていき、背景全体が色Aにもどる。この時、色Bと色Aの境界はグラデーションにする。 少し調べてみると、グラデーションは<gradient>データ型を利用すれば問題なさそうだった。問題は、グラデーションの境界位置をアニメーションする部分である。以下のように、ただ単に0%と100%のkeyframeを指定しただけでは、思ったようなアニメーションにならなかった。 See the Pen wrong case by kouya17 (@kouya17) on CodePen. 私の知識ではスマートなやり方が分からなかったので、keyframeを0%から100%まですべて指定する形で(無理やり)実装することにした。 keyframes生成用のpythonスクリプトを作成する pythonで、以下のようなkeyframes生成用のプログラムを作成した。 このスクリプトによって生成したテキストをkeyframesとしてCSSに貼り付けると、以下のようなアニメーションになる。 See the Pen linear by kouya17 (@kouya17) on CodePen. とりあえずやりたいことは出来た。しかし、完成したアニメーションを見ると、動きにメリハリがない。アニメーションの進行具合はCSSの`animation`要素の`animation-timing-function`プロパティを設定すればいじることができる。 ただ、今回のパターンだと、うまく設定できないようだ。下の例はanimation-timing-functionプロパティをlinearとease-in-outにそれぞれ設定したものを並べた例である。それぞれのアニメーションの進行具合に違いが生じるはずだが、特に差がない。 See the Pen linear and ease-in-out by kouya17 (@kouya17) on CodePen. 先ほど作成したpythonスクリプトを修正して、イージングの要素も取り入れることにする。 イージングの要素を実装する イージングの要素を実装するには、3次ベジェ曲線について把握しておく必要がある。ベジェ曲線については以下の記事を参考にさせていただいた。 pythonでベジェ曲線生成クラスを作成する pythonでベジェ曲線を生成するためのクラスを以下のように作成した。 上のスクリプトを実行すると p0=[0,0], p1=[0,1], p2=[1,0], p3=[1,1] とした時の3次ベジェ曲線が生成される。グラフにプロットすると以下のような曲線になる。 keyframes生成用のpythonスクリプトを修正する 先ほど作成したkeyframes生成用のスクリプトにベジェ曲線生成用クラスを組み込む。組み込んだ後のスクリプトは以下のようになる。 このスクリプトを使って、 p0=[0,0], p1=[0,0....

February 7, 2021 · 1 min

ロジスティック回帰を使ってYouTubeタイトルから投稿者を推論する

Pythonでロジスティック回帰を使って、VTuberの動画タイトルから投稿者を推論してみる。 ただ、投稿者を推論するといっても、二値分類なので、投稿者が A か B かを分類するのみ。 使用するライブラリ 今回は以下のライブラリを使用する。 scikit-learn : テキストのベクトル化、ロジスティック回帰 MeCab : 日本語形態素解析 データセット 適当に選んだRan Channel / 日ノ隈らん 【あにまーれ】さんとKuzuha Channelさんの動画タイトルをデータセットとして使う。 動画タイトルはYouTube Data APIを使って取得した。 1日のAPIリクエスト上限に引っかかって、すべては取得できなかったが、日ノ隈らんさんのタイトルは475個、葛葉さんのタイトルは456個取得できた。 タイトル取得に使用したプログラムは以下に置いてある。 また、タイトル中の【】内には大体投稿者名が入っている。 これを使うと簡単に分類できてしまうと思うので、今回は削除する。 (まあ、【】内でなくても、投稿者名が入っていることがあるので結局、というところもあるが…) プログラムと推論結果 今回推論に使用したプログラムは以下に置いてある。 テストデータは直近(このプログラムを作成中)に投稿された以下のタイトルを使う。 Ice breaker / ChroNoiR けんきさんとあびつんさんとランクいってくる!!! 1行目が葛葉さんの動画タイトルで、2行目が日ノ隈らんさんの動画タイトルになっている。 推論結果 推論結果は以下のようになった。 [0.45 0.69] なお、1個目が1行目の結果で、2個目が2行目の結果になる。 また、この結果が 1.0 に近いほど日ノ隈らんさんのタイトル、 0 に近いほど葛葉さんのタイトル"っぽい"と判断できる。 推論結果の分析 どういった理由で今回の推論結果が出たのか分析する。 ロジスティック回帰では各特徴量の係数(重み)と切片(バイアス)を見ることができる。 今回の特徴量はタイトルに含まれる単語なので、各単語について係数(重み)を見てみる。 まず1行目のタイトルの各単語の結果は以下の通り。 以下でwordとtf_idfというラベルで出力しているものが、それぞれ単語名及びtf-idfという手法によって得られた、各単語の重要度になる。 ただ、このデータに関してはすべての単語について、学習元データに含まれていなかったため、this word does not existと表示されている。 つまり、上記推論結果で0.45と出ているが、これは切片(バイアス)成分によるものである。 title_index: 0 word: Ice tf_idf: this word dose not exist word: breaker tf_idf: this word dose not exist word: / tf_idf: this word dose not exist word: ChroNoiR tf_idf: this word dose not exist 次に2行目のタイトルの各単語の結果は以下の通り。...

May 25, 2020 · 2 min

全国規模の感染シミュレーションと結果の可視化をしてみる

先日、都道府県間通勤・通学を考慮した感染症流行のシミュレーションを行った。 この時は関東のみのシミュレーションだったが、今回は全国規模の感染シミュレーションを実施してみる。 なお、この記事ではモデルに関する説明は特に記載しないため、モデルの詳細は以下過去の記事を参照していただきたい。 感染症数理モデルについて触りの部分だけ学ぶ | kouya17.com 都道府県間通勤・通学を考慮したパンデミックシミュレーションもどき | kouya17.com ※本シミュレーションや上記リンク先のシミュレーションは、実測値等には全く基づいていないため、完全に空想上のシミュレーションになります。 本シミュレーションの結果が実情を反映していたり、今後の予測を示していたりはしません。 利用するデータ シミュレーションを全国規模に拡張するには各都道府県の人口のデータと、各都道府県間の通勤・通学者人数のデータが必要になる。 これらのデータは総務省統計局「平成27年国勢調査結果」1を利用した。 パラメータ、初期状態について SEIRモデルに置ける各パラメータは今回以下のように設定する。 基本再生産数 \(R_0\) : 2.0 平均潜伏期間 \(l\) : 5日 平均発症期間 \(i\) : 14日 初期状態はAM0時に、東京都に1人の感染者がいる状態とする。 今回は都道府県間通勤・通学について 通勤・通学者なし 通勤・通学者あり、通勤・通学者数は特に加工しない 通勤・通学者あり、通勤・通学者数は元データの20%にする 通勤・通学者あり、通勤・通学者数は元データの0.01%にする の4パターン、計算を実施して、通勤・通学者数が与える影響を調べてみる。 また、前回のシミュレーションでは休日の概念を設けていなかった。 働きっぱなしは可哀想なので、土日は休みにし、通勤・通学はしないものとする。 ただし、祝日や土日以外の長期休暇は考慮しない。 結果及び可視化 今回はデータが少し多くなってくるので、可視化の方法も工夫する必要がある。 japanmapという、日本地図を都道府県別に色分けできるライブラリがあるようなので、これを利用させていただく。 発症者比率の可視化 各都道府県について、人口に占める発症者の比率(\(\frac{I}{S+E+I+R}\))を可視化する。 発症者の比率を赤色の濃淡で表したアニメーションを以下に示す。 通勤・通学者なしの場合 都道府県の人の移動が発生しないため、東京でしか流行しない。 通勤・通学者ありの場合 日本全国に感染が広がる。 ただし、感染のピークは東京から遠い都道府県ほど遅くなる。 通勤・通学者あり、ただし人数20%の場合 人数を絞る前の結果とほぼ変わらないように見える。 通勤・通学者あり、ただし人数0.01%の場合 人数を思いっきり絞ってみると、人数を絞る前と比べて感染が広がるスピードが遅いように見える。 1000日目時点での累計感染者数の可視化 それぞれの条件で1000日目時点での累計感染者数(\(E+I+R\))をグラフ化する。 横軸を各都道府県、縦軸を累計感染者数にした棒グラフを以下に示す。 通勤・通学における各条件の結果をそれぞれ色を変えて並べている。 累計感染者数に関しては、通勤・通学者数を絞っても変化はない。 ソースコード 今回使用したコードは以下に置いてある。 ただし、全然整理できていない…。 統計局ホームページ/平成27年国勢調査/調査の結果 ↩︎

May 20, 2020 · 1 min

LogisticRegression().fit()のConvergenceWarningを解消する

環境 Anacondaの環境情報 >conda info conda version : 4.8.2 conda-build version : 3.18.11 python version : 3.7.6.final.0 platform : win-64 現象 pythonでLogisticRegression.fit()を実行したところ、以下のワーニングが出た。 ConvergenceWarning: lbfgs failed to converge (status=1): STOP: TOTAL NO. of ITERATIONS REACHED LIMIT. 実行時のjupyter notebookは以下のような感じ。 一応正解率は出せているらしい。 解決策の1つ モデルが収束していないそうなので、max_iterを明示的に設定して、反復回数を増やす。 max_iterの初期値は100だが、上の例では1000に設定している。 今回はこれで警告が出なくなったので、よしとする。 参考 見て試してわかる機械学習アルゴリズムの仕組み 機械学習図鑑posted with ヨメレバ秋庭 伸也/杉山 阿聖 翔泳社 2019年04月17日 楽天ブックスで購入楽天koboで購入Amazonで購入Kindleで購入

May 16, 2020 · 1 min

都道府県間通勤・通学を考慮したパンデミックシミュレーションもどき

先日、SEIRモデルを用いた感染症流行のシミュレーションを行った。 このプログラムを少し拡張して、都道府県間通勤・通学を考慮したパンデミックシミュレーションもどきを行う。 ※本シミュレーションや上記リンク先のシミュレーションは、実測値等には全く基づいていないため、完全に空想上のシミュレーションになります。 本シミュレーションの結果が実情を反映していたり、今後の予測を示していたりはしません。 都道府県間通勤・通学をシミュレーションに組み込む 都道府県間通勤・通学の影響をシミュレーションに組み込むため、総務省統計局「平成27年国勢調査結果」1を参考にする。 今回は東京都・群馬県・栃木県・茨城県・埼玉県・千葉県・神奈川県間の自宅外就業者数及び通学者数データを扱う。 モデルへの組み込み方としては、移動用のグループを形成し、移動用のグループは移動先のデータと感染率を共有するという方法を採る。 なお、今回はシミュレーション内時刻が8:00の時に通勤・通学者が一斉に(移動時間0で)移動し、シミュレーション内時刻が17:00の時に通勤・通学者が一斉に(移動時間0で)帰宅すると仮定する。 東京都と千葉県間の人口移動を例にして説明する。 まず、初期状態として以下のような状態になっているとする。 値はすべて適当だが、東京都に10人感染者(\(I\))がいるとする。 この後、時間を進行させる。 シミュレーション内の時刻が8:00になった時、人口移動用のグループを分割する。 移動用グループの総人数は総務省統計局「平成27年国勢調査結果」1における自宅外就業者数及び通学者数に従う。 \(S:E:I:R\)比は移動元の都道府県データの比と等しくする。 ここで、移動用グループは移動先の都道府県のデータと、感染率\(\frac{R_0I}{iN}\)を共有する。 感染率を共有させた状態で、時間を進行させる。 なお、感染率を共有する関係で、非感染者から潜伏感染者への遷移に関する項については時間刻みに対して1次精度になってしまう。 シミュレーション内の時刻が17:00になった時、人口移動用のグループを移動元のデータに合流させる。 上の図中の値もすべて適当だが、以上のような形で、都道府県間の感染伝播をシミュレートする。 計算する 人口データについて 人口データは各自治体のページを参考に、以下の値を使う。 都道府県 人口[人] 備考 東京都 13951635 2020年1月1日時点推計2 茨城県 2866325 2020年1月1日時点推計3 栃木県 1942313 2019年10月1日時点推計4 群馬県 1938053 2019年10月1日時点推計5 埼玉県 7341794 2020年4月1日時点推計6 千葉県 6280344 2020年4月1日時点推計7 神奈川県 9204965 2020年4月1日時点推計8 各都道府県毎の通勤・通学による流入・流出人口は総務省統計局「平成27年国勢調査結果」1より、以下の値(単位は[人])を使う。縦が流出元で横が流出先。...

May 5, 2020 · 1 min

感染症数理モデルについて触りの部分だけ学ぶ

目的 特にしっかりした目的はない。 なんとなく数値シミュレーションについて学び直したくなったため、現在身近にある現象を題材にして学ぶ。 ネットの情報を参考に、適当にシミュレーションを走らせてみる。 ※本シミュレーションは、実測値等には全く基づいていないため、完全に空想上のシミュレーションになります。 本シミュレーションの結果が実情を反映していたり、今後の予測を示していたりはしません。 今回扱うシミュレーションモデル SEIRモデルを扱う。 SEIRモデルとは SEIRモデル(エスイーアイアールモデル)とは感染症流行の数理モデルである。 モデルは 感染症に対して免疫を持たない者(Susceptible) 感染症が潜伏期間中の者(Exposed) 発症者(Infectious) 感染症から回復し免疫を獲得した者(Recovered) から構成され、その頭文字をとってSEIRモデルと呼ばれる。 (Wikipediaより) モデル式は以下のような式で表される。 $$ \begin{aligned} \frac{dS}{dt} &= m(N - S) - bSI &(1) \cr \frac{dE}{dt} &= bSI - (m + a)E &(2) \cr \frac{dI}{dt} &= aE - (m + g)I &(3) \cr \frac{dR}{dt} &= gI - mR &(4) \end{aligned} $$ ここで\(t\)は時間、\(m\)は出生率及び死亡率、\(a\)は感染症の発生率、\(b\)は感染症への感染率、\(g\)は感染症からの回復率を表す。 また\(N\)は全人口を示し、 $$N \equiv S + E + I + R (5)$$...

May 2, 2020 · 2 min

カメラ画像から対象物の向きを検出する(OpenCV)

やりたいこと 俯瞰で見ているUSBカメラの画像を使って、自律的に動いているロボットの向きを検出する。 また、カメラ画像における指定の座標と、ロボットがなす角を算出する。 動作環境 ターゲットボード JetsonNano OS Ubuntu 18.04.4 LTS 使用ライブラリ Python版 OpenCV 4.1.1 処理結果 今回実装した処理の結果は、画像で示すと以下のような感じになる。 方法 今回実装した方法は以下の通り。 カメラ画像をHSV形式に変換 カメラ画像のうち指定のHSV範囲に従ってマスク画像を作成 マスク画像から輪郭を抽出し、1番面積の大きい領域のみ残したマスク画像を作成 カメラ画像とマスク画像の共通領域を抽出 4.で作成した画像から黒色領域を抽出 5.で抽出した黒色領域のうち、1番面積の大きい領域の重心p1、2番目に面積の大きい領域の重心p2を計算 p2からp1へのベクトルと、p1とp2の中点から指定の座標へのベクトルのなす角を計算 処理順に従って中間生成画像を並べると以下のような感じになる。 元画像 手順3.で作成したマスク画像 手順5.で抽出した黒色領域 手順6.で算出した各黒色領域の重心 処理結果 ソースコード 一部自作モジュールもimportしているのでコピペでは動きません。 呼び出し方は例えば以下のように。 処理時間や実行時のリソース使用量など 処理時間 今回の一連の処理呼び出しにどれだけ時間がかかっているか計測したところ、以下の通りだった。 elapsed_time:0.49050045013427734[sec] elapsed_time:0.500530481338501[sec] elapsed_time:0.49204468727111816[sec] だいたい0.5秒ほどかかっている。このままだとリアルタイム性が求められる場合は使えない。 リソース使用量 Jetsonのモニタツールjtopの出力は以下のような感じ。 プログラム稼働中 GPUが稼働していない。GPUを使うようにすれば高速化できるのだろうか(全然そこらへんは調べていない)。 なぜこの処理を実装したか 全体を俯瞰できるカメラの情報を使って、ロボットを指定位置に誘導したかった。 カメラ側がロボットに指定の位置に対する角度・距離情報を伝え、ロボット側でその情報を使って、モータ値を計算する。 設計の経緯や苦労したところなど 目印をどう設計するか 向き検出のための目印をどう設計するかが、検出精度や処理速度に最も影響を与える部分だと思う。 今回は黄色の画用紙の上に、面積の異なる黒色の画用紙を2つ(前方に面積が大きいもの、後方に面積の小さいもの)つけて目印にした。 単純だが、思っていたより認識出来ていたと思う。しっかりしたベンチマークはとっていないが。 最初はQRコードの活用を考えていた。OpenCVにはQRコード認識処理が実装されており、向きも検出出来そうだったので。今後複数台ロボットを同時に動かすことを考えても、QRコードだったら文字列情報を付加できるので、各ロボットの識別に使えそうとも思っていた。 ただ、ある程度QRコードが大きく写っていないと認識できなかった。今回はカメラと認識対象ロボットの距離が遠い時でも認識できるようにしたかったので、QRコード案はやめた。...

February 24, 2020 · 1 min