Android または iOS で初めてのコンピュータ ビジョン アプリを作成する

1. 始める前に

この Codelab では、コンピュータ ビジョンの主要なユースケースを処理するアプリを作成し、画像の主なコンテンツを検出します。一般には画像分類または画像ラベル付けと呼ばれます。

前提条件

この Codelab は、画像分類を使ってみるパスウェイの一部です。機械学習を初めて使用するデベロッパーを対象としています。

作成するアプリの概要

  • 花の画像を分類できる Android アプリ
  • (省略可)花の画像を分類できる iOS アプリ

必要なもの

  • Android Studio(https://developer.android.com/studio)にアクセスし、Codelab の Android の部分をご覧ください。
  • Apple App Store で入手できる、Codelab の iOS 部分に関する Xcode

2. 始める

コンピュータ ビジョンは機械学習のより広い分野の分野であり、機械学習によって、画像コンテンツから情報を処理して抽出する新しい方法を見つけようとします。コンピュータが画像を構成する実際のピクセルデータ(画像を構成するピクセルの値など)のみを保存する前は、コンピュータ ビジョンは画像の内容を解析して、画像に含まれる情報を取得します。

たとえば、コンピュータ ビジョンの分野では、猫の画像に、その画像を構成するピクセルに加えて猫が含まれるようにラベル付けできます。オブジェクト検出など、コンピュータ ビジョンの他の分野には他にもこの機能があります。オブジェクト検出では、コンピュータが画像内の複数のアイテムを検出して境界ボックスを導出できます。

この Codelab では、主要なユースケースを処理するアプリを作成し、画像の主要コンテンツを検出します。通常は画像分類または画像のラベル付けをご覧ください。

アプリをできるだけシンプルに保つため、アプリにバンドルされた画像がリソースとして使用され、分類が表示されます。今後、画像選択ツールを使用するか、カメラから直接画像を pull することも可能になります。

まず、Android Studio を使用して Android 上でアプリを作成するプロセスを行います。(ステップ 7 に進んで、iOS で同等の処理を行います)。

  1. Android Studio を開き、[File] メニューに移動して [Create a New Project] を選択します。
  2. プロジェクトのテンプレートを選択するよう求められます。[Empty Activity] を選択します。

Google

  1. [次へ] をクリックします。プロジェクトを設定するよう求められます。任意の名前とパッケージ名を付けますが、この Codelab のサンプルコードでは、プロジェクト名「ClassClassifierStep1」とパッケージ名「com.google.imageclassifierstep1」を使用しています。

ee3b6a81bad87b3.png

  1. 使用する言語(Kotlin または Java)を選択します。このラボでは Kotlin を使用するため、Kotlin を使用すると完了の選択肢が多くなります。
  2. 準備ができたら、[Finish] をクリックします。Android Studio によってアプリが作成されます。すべての設定が完了するまで少し時間がかかることがあります。

3. ML Kit の画像ラベル付けライブラリをインポートする

ML Kit(https://developers.google.com/ml-kit)にはデベロッパー向けのソリューションが多数用意されており、機械学習の一般的なシナリオに対応し、クロス プラットフォームでの実装と作業が簡単になります。ML Kit には、このアプリで画像ラベル付けと呼ばれるターンキー ライブラリが用意されています。このライブラリには、600 を超えるクラスの画像を認識するように事前にトレーニングされたモデルが含まれています。そのため、このテストは、

なお、ML Kit では、同じ API を使用してカスタムモデルを使用できます。準備が整ったら、ご自身のシナリオでトレーニングしたモデルを使用する、パーソナライズされた画像ラベル付けアプリの構築を開始できます。

このシナリオでは、花認識機能を構築します。最初のアプリを作成して花の画像を表示すると、そのアプリは花として認識されます。(後で独自の花の花束検出モデルを構築する際に、ML Kit によって最小限の変更でアプリにドロップできます。新しいモデルでは、その花の種類(チューリップやローズ)

  1. Android Studio のプロジェクト エクスプローラで、上部で [Android] が選択されていることを確認します。
  2. [Gradle Scripts] フォルダを開き、アプリの build.gradle ファイルを選択します。 2 つ以上の場所が存在する可能性があるため、以下に示すように app レベル 1 を使用していることを確認します。

2015-062195

  1. ファイルの下部には dependencies というセクションがあり、implementationtestImplementationandroidImplementation の設定のリストが格納されています。次のコードをファイルに追加します。
implementation 'com.google.mlkit:image-labeling:17.0.3'

(依存関係 { } の中にあることを確認します)。

  1. ウィンドウの上部に build.gradle が変更され、再同期が必要であることを示すバーが表示されます。これに進んでください。見つからない場合は、右上のツールバーで小さなアイコンを見つけてクリックします。

5ef40c7a719077a0.png

ML Kit がインポートされ、画像のラベル付けを開始する準備が整いました。

次に、画像をレンダリングするシンプルなユーザー インターフェースを作成します。このボタンを押すと、ML Kit が画像ラベラー モデルを呼び出して画像の内容を解析するボタンが表示されます。

4.ユーザー インターフェースを作成する

Android Studio では、XML ベースのレイアウト ファイルを使用して、各画面(またはアクティビティ)のユーザー インターフェースを編集します。作成した基本アプリには、1 つのアクティビティ(コードは MainActivity にあり、まもなく表示されます)と、ユーザー インターフェース宣言は activity_main.xml にあります。

これは、次のように Android のプロジェクト エクスプローラの res > layout フォルダにあります。

3.772e9563061e9.png

Activity のユーザー インターフェースをデザインできるフル エディタが開きます。0:10:52.000, 0:10:59.680 多くの内容が掲載されていますが このラボの目的は使用方法を解説することです Layout Editor の詳細については、https://developer.android.com/studio/write/layout-editor をご覧ください。

このラボでは、エディタの右上にある [Code(ツール)] を選択します。

1f7dbdef48d9ade6.png

ウィンドウのメイン部分に XML コードだけが表示されます。コードを次のように変更します。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/imageToLabel"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <Button
            android:id="@+id/btnTest"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Label Image"
            android:layout_gravity="center"/>
        <TextView
            android:id="@+id/txtOutput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:gravity="start|top" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

これにより、ImageView(画像をレンダリングするため)、Button(ユーザーが押すため)、およびラベルが表示される TextView を含む、非常にシンプルなレイアウトが提供されます。

これで、ユーザー インターフェースが定義されました。コーディングに進む前に、画像を画像として追加すると、アプリで画像に対して推論が行われます。

5. アプリで画像をバンドルする

追加ファイルを Android アプリにバンドルする方法の 1 つは、アプリにコンパイルされるアセットとしてファイルを追加することです。このアプリをシンプルにするため、いくつかの花の画像を追加します。後でこのアプリを拡張し、CameraX などのライブラリを使用して写真を撮影することもできます。ここでは簡単にするため、この画像をひとまとめにしておきます。

  1. プロジェクト エクスプローラ上部のアプリで、右クリックして [新しいディレクトリ] を選択します。
  2. 異なるディレクトリのリストが表示されたダイアログで、src/main/assets を選択します。

c93650ea68bb60e9.png

これを行うと、プロジェクト エクスプローラに新しい assets フォルダが表示されます。

444b4afab73433b8.png

  1. このフォルダを右クリックします。オプションのリストがポップアップ表示されます。そのうちの 1 つが、ファイル システムでフォルダを開くことです。 使用しているオペレーティング システムに合ったものを選択します。(Mac では [Finder に表示]、Windows では [Open in Explorer]、Ubuntu では [Show in Files] に表示されます)。 .)

275ec0881d35f6b.png

  1. ファイルをコピーします。Pixabay などのサイトから画像をダウンロードできます。画像の名前を簡単なものに変更することをおすすめします。この場合、イメージの名前は flower1.jpg に変更されています。

確認したら、Android Studio に戻ると、アセット フォルダにファイルが表示されます。

cfa53c9c75a033d8.png

この画像にラベルを付ける準備ができました。

6. 分類コードを記述して画像にラベルを付ける

(私たちが心待ちにしていた部分が、Android で Computer Vision を実行しました)。

  1. コードは MainActivity ファイルに記述するので、com.google.devrel.imageclassifierstep1 にあるプロジェクト フォルダ内(または、別の名前空間を選択した場合は同等の名前空間)内にあります。通常、Android Studio プロジェクトには、アプリ用、Android Test 用、テスト用に 3 つの Namespace フォルダが設定されます。MainActivity は、括弧で囲まれて説明が記述されていないファイルです。

b5aef8dd5e26b6c2.png

Kotlin を使用する場合、親フォルダの名前が「Java」なのか疑問に思われるかもしれません。これは、Android Studio が Java のみであったときの歴史的アーティファクトです。これは今後のバージョンで修正される可能性はありますが、Kotlin を使用する場合でも問題ありません。ソースコードのフォルダ名だけです。

  1. MainActivity ファイルを開くと、MainActivity という名前のクラスファイルがコードエディタに表示されます。確認します。
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

右中かっこの下には、クラスの一部ではないがクラスで使用できる拡張コードを追加できます。アセットからファイルをビットマップとして読み取るには、拡張子が必要です。これは、先ほどコピーした画像をアセット フォルダに読み込むために使用されます。

  1. 次のコードを追加します。
// extension function to get bitmap from assets
fun Context.assetsToBitmap(fileName: String): Bitmap?{
    return try {
        with(assets.open(fileName)){
            BitmapFactory.decodeStream(this)
        }
    } catch (e: IOException) { null }
}

この時点で Android Studio はエラーとなり、ContextBitmapIOException などのコードの一部は赤色でハイライト表示されます。

d2bde17e3c04aeed.png

これは、そのライブラリを含むライブラリをまだインポートしていないためです。Android Studio の便利なショートカットをご紹介します。

  1. 目的の単語の上にカーソルをドラッグして Alt+Enter(Mac の場合は option+enter)を押します。インポートが生成されます。
  2. 次に、アセットからビットマップを読み込み、ImageView に配置できます。MainActivity の onCreateFunction に戻り、setContentView 行のすぐ下に次のコードを追加します。
val img: ImageView = findViewById(R.id.imageToLabel)
// assets folder image file name with extension
val fileName = "flower1.jpg"
// get bitmap from assets folder
val bitmap: Bitmap? = assetsToBitmap(fileName)
bitmap?.apply {
    img.setImageBitmap(this)
}
  1. 前と同様に、コードの一部は赤色でハイライト表示されます。その行にカーソルを置き、Alt+Enter または Option+Enter キーを押してインポートを自動的に追加します。
  2. 先ほど作成した layout.xml ファイルで、ImageView に imageToLabel という名前を付けたため、最初の行で、そのレイアウト情報を使用して、ImageView オブジェクトのインスタンスを img という名前で作成します。Android の組み込み関数である findViewById を使用して詳細を確認します。次に、flower1.jpg というファイル名で、前の手順で作成した assetsToBitmap 関数を使用して assets フォルダから画像を読み込みます。最後に、ビットマップ抽象クラスを使用して、ビットマップを img に読み込みます。
  3. レイアウト ファイルには、画像に対して推測されたラベルのレンダリングに使用する TextView がありました。次に使用するコード オブジェクトを取得します。前のコードのすぐ下に次のコードを追加します。
val txtOutput : TextView = findViewById(R.id.txtOutput)

前に説明したとおり、テキストビューのレイアウト ファイル情報の名前(txtOutput という名前の XML を確認)を使用して、txtOutput という TextView オブジェクトをインスタンス化します。

同様に、ボタンを表すボタン オブジェクトを作成し、レイアウト ファイルの内容でインスタンス化します。

レイアウト ファイルで btnTest ボタンを呼び出し、次のようにインスタンス化しました。

val btn: Button = findViewById(R.id.btnTest)

これですべてのコードとコントロールが初期化されました。次のステップ(および最後のステップ)では、それらを使用して画像について推論を行います。

続行する前に、onCreate コードが次のようになっていることを確認します。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val img: ImageView = findViewById(R.id.imageToLabel)
    // assets folder image file name with extension
    val fileName = "flower1.jpg"
    // get bitmap from assets folder
    val bitmap: Bitmap? = assetsToBitmap(fileName)
    bitmap?.apply {
        img.setImageBitmap(this)
    }
    val txtOutput : TextView = findViewById(R.id.txtOutput)
    val btn: Button = findViewById(R.id.btnTest)
}

まだ読み込まれていないキーワードには、赤色のキーワードは表示されません。インポートされている場合は、Alt+Enter キーを押して、インポートを生成してください。

ML Kit の画像ラベラーを使用する場合、まず、Options オブジェクトを作成して動作をカスタマイズします。画像を、ML Kit で認識できる InputImage 形式に変換します。次に、推論を実行する Labeler オブジェクトを作成します。その結果を非同期で返すため、解析できます。

作成したボタンでは、onClickListener イベント内ですべての操作を行います。完全なコードは次のとおりです。

btn.setOnClickListener {
  val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)
  val image = InputImage.fromBitmap(bitmap!!, 0)
  var outputText = ""
  labeler.process(image)
    .addOnSuccessListener { labels ->
      // Task completed successfully
      for (label in labels) {
        val text = label.text
        val confidence = label.confidence
        outputText += "$text : $confidence\n"
      }
      txtOutput.text = outputText
  }
    .addOnFailureListener { e ->
      // Task failed with an exception
  }
}
  • ユーザーが最初にボタンをクリックすると、コードは ImageLabeling.getClient を使用してラベラーをインスタンス化し、ImageLabelerOptions を渡します。これには、すぐに使用を開始できる DEFAULT_OPTIONS プロパティが付属しています。
  • 次に、inputImage を fromBitmap メソッドを使用してビットマップから作成します。InputImage は、画像の処理に必要な ML Kit の形式です。
  • 最後に、ラベル付け担当者は画像を処理し、成功または失敗したときに非同期コールバックを行います。推論が成功した場合、コールバックにラベルのリストが含まれます。このラベルリストを解析して、ラベルのテキストと信頼値を読み取ることができます。失敗した場合は、ユーザーに例外を返します。この例外はユーザーに報告できます。

これで完了です。これで、Android デバイスまたはエミュレータ内でアプリを実行できるようになりました。初めての場合は、https://developer.android.com/studio/run/emulator をご覧ください。

エミュレータで実行されているアプリは次のとおりです。最初に画像とボタンが表示され、ラベルは空になります。

c07f5f307f070dc7.png

ボタンを押すと、画像のラベルが表示されます。

550ccaa783363551.png

ラベル付け担当者は、この画像に花、花、植物、空が含まれている可能性が高いと判断しました。これらはすべて正しいもので、モデルが画像の解析に取り組んでいることを示しています。

まだデイジーの写真かどうかはまだ確認できません。それには、特定の花でトレーニングされたカスタムモデルが必要です。その方法は次のラボで説明します。

次の手順では、iOS で同じアプリをビルドする方法について説明します。

7. iOS で画像分類を作成する - スタートガイド

Xcode を使用して、iOS で同様のアプリを作成できます。

  1. Xcode を起動し、ファイル メニューから [New Project] を選択します。このダイアログが表示されます。

17fb7e6a9d6ac275e.png

  1. 次に示すように [App] を選択し、[Next] をクリックします。プロジェクトのオプションを選択するよう求められます。次に示すように、名前と組織の ID を指定します。使用しているインターフェースの種類が [Storyboard] で、言語が [Swift] になっていることを確認します。

76c6bdb5aee7659c.png

  1. デベロッパー プロフィールを設定すると、スマートフォンにデプロイしてチーム設定を行うことができます。ない場合は、None のままにして、iOS シミュレータでアプリを実行します。
  2. [次へ] をクリックし、プロジェクトとそのファイルを保存するフォルダを選択します。このプロジェクトのロケーションを覚えておいてください。これは次のステップで必要になります。
  3. 次のステップの後に別のワークスペース ファイルを使用して再度開くため、今回は Xcode を閉じます。

8. CocoaPods を使用して ML Kit を統合する

ML Kit は iOS でも機能するので、画像分類器を作成する際に非常によく似た方法で使用できます。統合には CocoaPods を使用します。まだインストールしていない場合は、https://cocoapods.org/ の手順に沿ってインストールしてください。

  1. プロジェクトを作成したディレクトリを開きます。.xcodeproj ファイルが含まれているはずです。

ここに表示されるのは、正しい場所にいることを示す .xcodeproj ファイルです。

e2966a47e84eb398.png

  1. このフォルダに Podfile という名前の新しいファイルを作成します。拡張機能はありません。単なる Podfile です。その中に、次のコードを追加します。
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabeling'
end
  1. 保存して、ターミナルに戻ります。同じディレクトリで、「pod install」と入力します。CocoaPods が適切なライブラリと依存関係をダウンロードし、プロジェクトと外部依存関係を組み合わせた新しいワークスペースを作成します。

3b4c628b0cbface8.png

最後に、Xcode セッションを閉じて、今後はワークスペース ファイルを使用するよう求められます。このファイルを開くと、元のプロジェクトと外部依存関係とともに Xcode が起動します。

212-0034 32090e0024b6b5ef.png

次のステップに進み、ユーザー インターフェースを作成します。

9. ストーリーボードを使用して iOS UI を作成する

  1. Main.storyboard ファイルを開くと、スマートフォン用のデザイン サーフェスがユーザー インターフェース レイアウトに表示されます。
  2. 画面右上に [+] ボタンがあり、これを使用してコントロールを追加できます。これをクリックすると、コントロール パレットが表示されます。

e63bc3bafa54cc21.png

  1. そこから、ImageViewButtonLabel をデザイン サーフェスにドラッグ&ドロップします。次のように上から下へ並べます。

f9dfc55616b25f11.png

  1. ボタンをダブルクリックして、テキストを [ボタン] から [分類] に変更します。
  2. 拡大するには、コントロール ハンドルをラベルの周囲にドラッグします。(UIImageView とほぼ同じ幅で、高さは 2 倍にします)。
  3. ラベルがまだ選択された状態で、右上のセレクタ ボタンをクリックすると、インスペクタのパレットが表示されます。
  4. この操作が完了したら、[Lines] の設定を見つけて [0] に設定します。このようにすると、ラベルには動的な線の数を表示できます。

a39708b320b56b30.png

これで、次のステップとして、コンセントとアクションを使用して UI をコードに接続できるようになります。

10. アクションとアウトレットを作成する

ストーリーボードを使って iOS 開発を行う際は、コンセントを使ってコントロールのレイアウト情報を参照し、アクションを使ってユーザーがアクションを実行したときに実行するコードを定義します。

次のステップでは、ImageView と Label のアウトレットを作成する必要があります。ImageView は、画像を読み込むためにコード内で参照されます。ラベルはコード内で参照され、ML Kit から返された推論に基づいてテキストを設定します。

  1. 画面右上のコントロールをクリックしてインスペクタのパレットを閉じ、すぐ下の [Add Editor on Right] ボタンをクリックします。

77255F7d6284750.png

  1. また、main.storyboard を 2 回開くとわかりにくい画面レイアウトになります。左側にあるプロジェクト ナビゲータで、[ViewController.swift] を選択してビュー コントローラ コードを開きます。デザイン サーフェスは左側のストーリーボード エディタから消えているように見えますが、まだ残っています。
  2. 元に戻すには、[View Controller] シーンで [View Controller] をクリックします。UI が次のようになるようにします。左側のストーリーボードにデザインが表示され、右側に ViewController.swift のコードがあります。

7eb21c7f9d43c9bc.png

  1. 左側のデザイン サーフェスから UIImageView を選択し、Ctrl キーを押しながら右側のコードにドラッグして、class キーワードのすぐ下(上のスクリーンショットの 11 行目)にドロップします。

ドラッグすると矢印が表示され、ドロップすると以下のようなポップアップが表示されます。

2016-0614

  1. [名前] フィールドに「imageView」と入力し、[接続] をクリックします。
  2. このプロセスをラベルで繰り返し、「lblOutput」という名前を付けます。
  3. 重要: ボタンについては、接続タイプを [コンセント] ではなく [アクション] に設定してください。

7281b6eea9fb6c23.png

  1. 「doClassification」という名前を付け、[接続] をクリックします。

完了すると、コードは次のようになります(ラベルと画像ビューは IBOutlet(Interface Builder Outlet)として宣言され、ボタンは IBAction(Interface Builder Action)です)。

import UIKit

class ViewController: UIViewController {

    @IBAction func doClassification(_ sender: Any) {
    }
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var lblOutput: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

}
  1. 最後に、分類しやすいようにアプリに画像をバンドルします。それには、ファイル エクスプローラから Xcode の左側にあるエクスプローラにファイルをドラッグします。ドロップすると、次のようなポップアップが表示されます。

10606446660060 e コマース

  1. [Add to Targets] セクションのチェックボックスがオンになっていることを確認し、[Finish] をクリックします。

このファイルはアプリにバンドルされ、簡単に分類できます。これで、ユーザー インターフェースをコーディングして画像分類を行う準備が整いました。

11. 画像分類用のコードを作成する

すべての設定が完了したら、画像分類を実行するためのコードを記述することは本当に簡単になります。

  1. まず、デザイン サーフェスの左上にある [X] をクリックして、ストーリーボード デザイナーを閉じます。これにより、コードのみに集中できます。後ほど、ViewController.swift を編集します。
  2. MLKitVision ライブラリと MLKit ImageLabeling ライブラリをインポートするには、UIKit のインポートすぐ下の次のコードを追加します。
import MLKitVision
import MLKitImageLabeling
  1. 次に、viewDidLoad 関数内で、アプリにバンドルしたファイルを使用して ImageView を初期化します。
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    imageView.image = UIImage(named:"flower1.jpg")
}
  1. 画像のラベルを取得するヘルパー関数を作成します(viewDidLoad() のすぐ下)。
func getLabels(with image: UIImage){
  1. 画像から VisionImage を作成します。ML Kit では、画像分類を行う際にこのタイプが使用されます。したがって、getLabels 関数内に次のコードを追加します。
let visionImage = VisionImage(image: image)
visionImage.orientation = image.imageOrientation
  1. 次に、画像ラベラーのオプションを作成します。これらのオプションを使用して初期化されます。この場合は、confidenceThreshold の基本オプションを設定するだけです。つまり、0.4 以上の信頼度を持つラベルのみを返すようにラベル付け担当者に依頼するだけです。たとえば、当社の花の場合、「植物」や「花びら」のようなクラスの信頼度は高くなりますが、「バスケットボール」や「車」などのクラスは信頼度が低くなります。
let options = ImageLabelerOptions()
options.confidenceThreshold = 0.4
  1. 次に、以下のオプションを使用してラベラーを作成します。
let labeler = ImageLabeler.imageLabeler(options: options)
  1. ラベル付け担当者は、その処理を行うことができます。これにより、ラベル(成功した場合)とエラー(失敗した場合)を含む非同期コールバックが提供されます。これについては、後で作成する別の関数で処理できます。
labeler.process(visionImage) { labels, error in
    self.processResult(from: labels, error: error)
  }

Xcode に processResult のメンバーはいないという苦情があっても問題ありません。これはまだ実装していませんが、これは次のステップで行います。

便宜上、getLabels の完全な関数を次に示します。

// This is called when the user presses the button
func getLabels(with image: UIImage){
    // Get the image from the UI Image element and set its orientation
    let visionImage = VisionImage(image: image)
    visionImage.orientation = image.imageOrientation

    // Create Image Labeler options, and set the threshold to 0.4
    // so we will ignore all classes with a probability of 0.4 or less
    let options = ImageLabelerOptions()
    options.confidenceThreshold = 0.4

    // Initialize the labeler with these options
    let labeler = ImageLabeler.imageLabeler(options: options)

    // And then process the image, with the callback going to self.processresult
    labeler.process(visionImage) { labels, error in
        self.processResult(from: labels, error: error)
 }
}

そのため、processResult 関数を実装する必要があります。ラベルとエラー オブジェクトが返されるので、これは非常にシンプルです。ラベルは ML Kit の ImageLabel タイプにキャストする必要があります。

そのうえで、ラベルのセットを反復処理し、説明と信頼値を取得し、labeltexts という var に追加します。反復処理が完了したら、lblOutput.text にその値を設定するだけです。

関数全体は次のとおりです。

// This gets called by the labeler's callback
func processResult(from labels: [ImageLabel]?, error: Error?){
    // String to hold the labels
    var labeltexts = ""
    // Check that we have valid labels first
    guard let labels = labels else{
        return
    }
  // ...and if we do we can iterate through the set to get the description and confidence
    for label in labels{
        let labelText = label.text + " : " + label.confidence.description + "\n"
        labeltexts += labelText
    }
    // And when we're done we can update the UI with the list of labels
    lblOutput.text = labeltexts
}

あとはユーザーがボタンを押したときに getLabels を呼び出すだけです。

アクションが作成されたとき、すべてが接続されたので、先ほど作成した doClassificaiton という IBAction を更新して getLabels を呼び出すようにします。

imageView のコンテンツを使用して呼び出すコードは次のとおりです。

@IBAction func doClassification(_ sender: Any) {
    getLabels(with: imageView.image!)
}

アプリを実行して、試してみましょう。実際の動作についてはこちらをご覧ください。

eb8e6c1b2e2c65e0.png

レイアウトは端末によって異なる場合があります。

この Codelab は、デバイスごとに異なるレイアウト タイプを実行するわけではありません。これは、それ自体が非常に複雑な概念です。UI が表示されない場合は、ストーリーボード エディタに戻ると、下部に [View as:] セクションが表示され、特定のデバイスを選択できます。テスト対象のイメージまたはデバイスに合わせて 1 つを選択し、それに合わせて UI を編集します。

iOS 開発を続ける中で、制約を使用して UI の一貫性をスマートフォン間で確保する方法を学びますが、このラボの範囲外です。

12. 完了

Android と iOS の両方で、汎用的なモデルによる基本的なコンピュータ ビジョンを提供するアプリを実装できました。手間のかかる作業の大部分は完了しました。

次の Codelab では、さまざまな種類の花を認識するカスタムモデルを作成します。このアプリには数行のコードで、カスタムモデルを実装してさらに便利に使用できます。