機械学習、盛り上がり続けてますね。今回はiOS/Androidで機械学習による解析が行えるFirebase ML Kitの勉強会に行ってきました。
実際に会場で試した内容を紹介したいと思います。とりあえず動かしてみるだけなら簡単ですので、Android実機をお持ちであれば、ぜひ試してみてください。
機能 | on-device | cloud | |
---|---|---|---|
テキスト認識 | ○ | ○ | 画像を読み込んでテキスト抽出 |
顔検出 | ○ | × | 画像を読み込んで人の顔を検出 |
バーコードスキャン | ○ | × | そのまま。バーコード読み取り。 |
画像のラベル付け | ○ | ○ | 画像を読み込んでラベリング |
ランドマーク認識 | × | ○ | 画像内のランドマーク(東京タワー、スカイツリーetc.)を認識 |
カスタムモデルの利用 | ○ | × | 独自のTensorflow LiteモデルをFirebaseにアップロードして、アプリで使える |
エミュレータでも動作するので実機必須ではありませんが、できれば実機でいろいろ写真を撮って試すのをおすすめします。
https://github.com/yanzm/MLKitSample からgit cloneして、課題1・課題2までを終えれば準備完了です。
課題2-1で「デバッグ用の署名証明書」は省略可ですので、空欄のままでOKです。
会場で私を含め何人かが遭遇していた現象で、AndroidStudioが最新版(3.1.3)になっていないことが原因だったようです。
素直にAndroidStudioをバージョンアップしてもいいのですが、Kotlinのバージョン指定を書き換えることでもひとまず解決できます。
私の場合(3.0.1)では、build.gradleに記述されているKotlinのバージョンを1.2.51
から1.2.41
に変更することで、syncできるようになりました。
画像を読み込み、テキストを抽出します。MainActivity.kt#detect
に下記リンクからコードを追加します。
課題3 : テキスト認識
private fun detect(bitmap: Bitmap) { overlay.clear() val detectorName = detectorSpinner.selectedItem as String when (detectorName) { TEXT_DETECTION -> { // TODO: 1 on-device テキスト認識 // https://firebase.google.com/docs/ml-kit/android/recognize-text#on-device detectButton.isEnabled = false progressBar.visibility = View.VISIBLE val image = FirebaseVisionImage.fromBitmap(bitmap) FirebaseVision.getInstance() .visionTextDetector .detectInImage(image) .addOnSuccessListener { texts -> detectButton.isEnabled = true progressBar.visibility = View.GONE for (block in texts.blocks) { for (line in block.lines) { for (element in line.elements) { element.boundingBox?.let { overlay.add(BoxData(element.text, it)) } } } } } .addOnFailureListener { e -> detectButton.isEnabled = true progressBar.visibility = View.GONE e.printStackTrace() } } FACE_DETECTION -> { ...
firebaseのwebページを実機で撮影、処理してみると以下のようになります(on-deviceのため、日本語は認識できません)。
文字が重なっててよくわからない!という場合は、GraphicOverlay.kt
内のtextSize
を変更してみましょう。
private val textPaint = Paint().apply { color = Color.WHITE textSize = 20 * resources.displayMetrics.density }
画像を読み込み、何が写っているのかを解析・表示します。MainActivity.kt#detect
に、下記リンクからコードを追加します。
課題7 : 画像のラベル付け
private fun detect(bitmap: Bitmap) { overlay.clear() val detectorName = detectorSpinner.selectedItem as String when (detectorName) { // 中略 LABELING -> { // TODO: 4 on-device ラベルづけ // https://firebase.google.com/docs/ml-kit/android/label-images#on-device detectButton.isEnabled = false progressBar.visibility = View.VISIBLE val image = FirebaseVisionImage.fromBitmap(bitmap) val options = FirebaseVisionLabelDetectorOptions.Builder() .setConfidenceThreshold(0.5f) // スコア0.5未満は解析結果に表示しない .build() FirebaseVision.getInstance() .getVisionLabelDetector(options) .detectInImage(image) .addOnSuccessListener { labels -> detectButton.isEnabled = true progressBar.visibility = View.GONE overlay.add(TextsData(labels.map { "${it.label}, ${it.confidence}" })) } .addOnFailureListener { e -> detectButton.isEnabled = true progressBar.visibility = View.GONE e.printStackTrace() } } }
「Tableware」「Cutlery」等がラベル名です。その横の数字はラベルのスコアで、1.0に近づくほど確度が高いことを意味しています。スコアが0.9
を超えるラベルはほぼ間違いがなく、0.8でも大体合っているという印象です。
多言語対応のテキスト認識や高精度のラベル付け、またランドマーク認識などを処理できますが、こちらはまだ試していません。近い内に試してみて、ご紹介したいと思います。
カスタムモデルについてはきちんと理解できているか怪しいですが、TensorFlow Liteの独自モデルを使うことで、テキスト認識や画像のラベル付けで、より個々の目的に特化した解析ができるようになるのだと思います。
興味はありつつ後回しにしていた機械学習ですが、少し学んでみたいと思っています。
いかがでしたでしょうか。私は機械学習と言われるものに触れるのは今回が初めてでしたが、驚くほど簡単に試すことができました。
試して遊ぶ分には面白いのですが、実案件で使うものではないという印象です(まだベータ版ですし…)。
また、アプリと一緒にカスタムモデルを端末に入れて解析に使うこともできますが、root化された端末ではモデルの中身を覗けてしまう可能性があったりと、Googleの中の人いわく「セキュリティについてはこれから検討していく」とのことでした。