TensorFlow LiteをKotlinから使う 2/3

android

はじめに

最近はAndroidの開発はkotlinだ!という風潮が強いので、AIを勉強し始めたばかりの私が、TensorFlow Liteをkotlinで使ってみたよ。

ちょっと長いので全3回に分けます。今回は2回目。サンプルアプリのClassifierを作成します。

 

前提

前回までで、モデルの組み込みまで終わりました。

今回は、サンプルアプリを作っていこうと思います。

 

サンプルアプリの作成

サンプルアプリについて

さて、これでTensorFlow Liteを用いてサンプルアプリを作成する準備ができました。では、ここからは、「サンプルアプリとして何を作るか?」ですね。

今回は、とてもシンプルなサンプルを作成することにしたいと思います。

このアプリは「ユーザが指定したファイルを識別する」という単純な機能を持つこととします。

アプリの画面は、次の二つのエリアから構成されます。

  1. 画像表示エリア
  2. その表示された画像が何を映しているかを示すてテキストエリア

画像表示エリアをタップすると、画像選択画面に遷移し、そこで選択した画像が画像表示エリアに表示されます。そして、これ同時に、その画像が何を示しているかを推測してテキストエリアに表示します。イメージとしては↓のような感じ。

Classifier

画像を識別するためのクラスを作成します。

基本は、SampleのClassifierを参考に作るのが良いと思います。今回はImageClassifierFloatInceptionを参考に作成します。

Classifierの生成

Classifierは、複数あっても仕方がないのでsingletonで生成されるようにしておきます。(今回のデモではあまり意味はないけど、どっかで再利用したいので。) こんな感じのcompanion objectを作ればいいかな。

生成元がcreateメソッドを呼ぶ際に、モデルとラベルのパスと画像の解像度を教えてあげて、この情報を元にClassifierを生成しています。

このcreateメソッドの中ではInterfpreterをメンバ変数として生成しています。Interpreterのコンストラクタにはモデルを渡す必要がありますので、モデルファイルをMappedByteBuffereにマップして渡します。(普通のByteBufferだと”Model ByteBuffer should be either a MappedByteBuffer of the model file, or a direct ByteBuffer using ByteOrder.nativeOrder() which contains bytes of model content.”と怒られます。)

まずは次のようなMappedByteBufferを返すメソッドを作ります。

で、こんな風にInterpreterを生成してあげましょう。

次に、labelのリストも読み込んでおきます。

同じく、こんな感じでClassifierオブジェクトのメンバ変数に設定してあげます。

これで、Interpreterを起動することができます。

Interpreterの起動

Interpreter起動用のメソッドとして、recognizeImageメソッドを作成します。

 

入力として、認識対象となる画像のbitmapを受け付けます。そして、認識可能なサイズに画像をリサイズしています。

このリサイズした画像のBitmapをconvertBitmapToByteBufferメソッドでbyteBufferに変換します。この変換メソッドは次のようなものになります。各ピクセルはARGBではなくRGBで評価される(?)ようなので、PIXEL_SIZEは3です。

各ピクセルの32bit列(=Int値)からRGBの値を取り出して、ノーマライズ(?)してbyteBufferに追加していきます。ノーマライズの方法はサンプルを参考にコピペしているので詳細は分かってないです。いずれ勉強してわかるようになります。(人;´Д`) ゴメンナサイ!

このbyteBufferをInterpreter.run()に入力して、画像認識を開始。各ラベルに対する信頼度が配列として取得できるので、getSortedResultメソッドを使ってこれを信頼度の高い順にソートしています。

ソートの仕方は一般的な方法なので、ここでは割愛します。

以上で、Classifierを作れました。

あとは、これを利用するActivityを作成してあげるだけですね。次回説明します。

 

 

コメント