茨城エンジニアのPython開発日記

茨城のITベンチャー企業ではたらく2年目エンジニア。Pythonで色々なものを作成中。

AIをARに応用するぞ会 → (第6回) ~基本設計~


ブログから記事を見つけたい場合はこちら

ブログ地図 - 茨城エンジニアのPython開発日記

こんにちは。

開発メンバーのKです。
最近、雨がよく降りますね。
じめじめする夏が近づいているんですね。。。
湿気が多いのは嫌ですね。

さて今回は、スマホでAIを動かすことにあたり、要件定義をしました。


以下、目次です。

1. 前回まで


↓前回のブログ
https://tottorisnow33.hatenablog.com/entry/2021/06/26/103702

前回は入力画像がラーメンかどうか識別する処理をスマホで動かせるように実装しました。
(とはいっても、まだAndroid studio上ですが)

おかげで、javaでtfliteを使うことやり方がだいたいわかりました。
これを踏まえて今回から実際にスマホにARアプリを入れるのを頑張っていきます。
そこで今回は「商品化できそうな見栄えのスマホアプリ」を目指して要件定義してみました。

2. どんな感じのスマホアプリにするか

僕は映画好きでミッションインポッシブルをよく観ます。
それに出てきそうなものを作りたいと言ったら、みんな賛同してくれました。

具体的にはどんなものかというと、スマホのカメラを人に向けたら、
スマホの画面上にその人に枠がついて、それからぴょこんとその人の情報が出てくるものです。
個人的にはそれをかっこよくなるように、デザインや表示の仕方も懲りたいですね。

3. 基本設計

ざっくりですが基本設計をしてみました。
どんな処理をどんなフローで行うのか、どんな風に表示するのかを以下にまとめてみました。

f:id:tottorisnow33:20210626115559p:plain
基本設計_ARアプリ

スマホ上で動かすとなると処理時間が気になります。
特に検知(物体を検知してBounding Boxを入れるための座標情報を得る)と、識別(対象画像が人A, 人B ... or 人N のどれなのかを識別して、DBから情報を引っ張ってくる)あたりの処理が重いかなと思ってまいす。
ある時刻でカメラで画像を取ったとして、すべての処理が終わってから次にカメラで画像を取るまでに何[ms]かかるのか怖いです。

そこで今回はとりあえず、検知と識別は切り分けて考えています。
つまり、はじめは人の検知処理だけ動かして、人の検知ができたらカメラで映像を取得するのはいったんやめて画像だけ持っておき、その画像に対してゆっくりと識別をするという流れです。
こうすれば、カメラの映像取得に追いつくために、検知の処理速度だけ考えれば良くなります。

4. main関数

上記の基本設計を踏まえて、main関数だけ作ってみました。
main関数を書いたおかげで具体的にどんなフローにするべきか、クラスにどんな情報を持たせておくと良さそうか見えてきました。
ただ、1つ1つのクラスや関数の詳細設計はまだです。

private main()
{

    // フレームループ
    while(1)
    {
        /* カメラで映像取得 */
        float[][][][] image = cameraCapture();

        /* 検知 */
        /* class BBoxesには、class BBox(検知数分)とhumanが含まれるかどうかの情報を持つ */
        BBoxes predBBoxes = detectImage(image);

        if (predBBoxes.haveHuman == true && predBBoxes.shouldDraw)
        {
            /* HumansInformationには、対象となる人たちのすべての情報が入る */
            HumanInformations targetHumans = new HumanInformations();

            /* BBoxesから識別及び描画する対象を選出 */
            selectTargets(targetHumans, predBBoxes);

            /* 人が移った領域を画像として取得 */
            cropImage(targetHumans, image, predBBox);

            /* 識別(データベースの中から選出) */
            classification(targetHumans);

            /* 最終画面描画処理 */
            drawResult(image, predBBox, targetHumans);

            /* タップしたら、カメラの映像取得ループに戻る */
            returnCamCap();
        }
    }
}

5. 次回から

今回基本設計をしてメイン関数を作ったので、次回からは1つ1つの関数の詳細設計をして、実装していきます。
とりあえず次回は「最終画面描画処理」の手前まで形にしたいです。