在 Android 或 iOS 上建構您的第一個電腦視覺應用程式

1. 事前準備

在本程式碼研究室中,您將瞭解如何建構可處理電腦視覺核心用途的應用程式,偵測圖片的主要內容。這通常稱為「圖片分類」或「圖片標籤」

必要條件

此程式碼研究室是開始使用圖片分類的一部分。本文適用於經驗豐富的機器學習開發人員。

建構項目

  • 可分類花卉圖片的 Android 應用程式
  • (選用) 可分類花卉圖片的 iOS 應用程式

軟硬體需求

  • Android Studio (位於 https://developer.android.com/studio,適用於程式碼研究室的 Android 部分)
  • 適用於程式碼研究室 iOS 部分的 Xcode (適用於 Apple App Store)

2. 開始使用

「電腦視覺」是機器學習領域中較廣的領域,它能夠尋找新的方法來處理機器,並擷取圖片內容中的資訊。如果電腦只儲存圖片的實際資料 (例如組成圖片的像素值),電腦視覺功能可讓電腦剖析圖片內容,並取得其中內容的相關資訊。

舉例來說,在 Computer Vision 的欄位中,除了圖片構成的像素之外,圖片也可以加上貓圖片。有些電腦視覺欄位還有更多細節 (例如「物件偵測」),能讓電腦找出圖片中的多個項目,並產生對應的定界框。

在本程式碼研究室中,您將瞭解如何建構可處理核心用途的應用程式,並偵測圖片的主要內容。這通常稱為「圖片分類」或「圖片標籤」

為了儘可能讓應用程式保持精簡,應用程式會隨隨附資源的圖片使用,並顯示分類結果。日後的擴充功能可以使用圖片挑選器,或是直接從相機中提取圖片。

系統會逐步引導您使用 Android Studio 建立 Android 應用程式,(請跳至步驟 7,在 iOS 上進行同等操作)。

  1. 開啟 Android Studio,前往 [File] (檔案) 選單,然後選取 [Create a New Project] (建立新專案)。
  2. 系統會請你挑選專案範本。選取 [空白活動]。

859b1875e37c321a.png

  1. 按一下 [繼續],系統會要求您設定專案。指定任何所需的套件名稱和套件名稱,但這個程式碼研究室中的程式碼範例使用專案名稱 ImageClassifierStep1 和套件名稱 com.google.imageclassifierstep1。

ee3b6a81bad87b3.png

  1. 選擇您偏好的語言 (Kotlin 或 Java)。這項研究室使用 Kotlin,因此如果您想確實瞭解,不妨選擇 Kotlin。
  2. 準備就緒後,按一下 [完成]。Android Studio 會自動為你建立應用程式。系統可能需要幾分鐘的時間才能完成所有設定。

3. 匯入機器學習套件圖片標籤庫

機器學習套件 (https://developers.google.com/ml-kit) 為開發人員提供了許多解決方案,可協助他們瞭解機器學習的常見情況,以及易於在跨平台導入和處理作業。ML Kit 提供了立即可用的程式庫,您可以在這個應用程式中使用圖片標籤功能。這個程式庫包含預先訓練的模型,可辨識超過 600 種圖片類別。因此,這是最適合開始使用這項功能的最佳選擇。

請注意,機器學習套件還可讓您使用同一個 API 來使用自訂模型。

在這個情境中,您會建立一個花卉辨識器。當您建立第一個應用程式並顯示「花卉」圖片後,系統就會將它視為花朵。(日後當您建立自己的花卉偵測模型時,則可透過機器學習工具將模型做些微小的變更,然後置入應用程式中)。此外,您還可以透過新模型判斷這是哪種類型的花卉,例如鬱金香或玫瑰。

  1. 在 Android Studio 中,使用專案多層檢視,確認已選取 [Android]
  2. 開啟「Gradle 指令碼」資料夾,然後為應用程式選取 build.gradle 檔案。檔案可能包含 2 個以上的檔案,所以請確認您使用的是 app 層級,如下所示:

93c2e157136671aa.png

  1. 您會在檔案底部看到名為「依附元件」的區段,系統會儲存「implementation」、「testImplementation」和「androidImplementation」設定的清單。使用下列程式碼新增檔案:
implementation 'com.google.mlkit:image-labeling:17.0.3'

(請確認這已出現在依附元件 { }) 中。

  1. 視窗頂端會顯示一個標記,指出 build.gradle 已變更,因此你必須重新同步處理。現在就進行吧!如果您沒有看到該圖示,請在右上方的工具列中尋找小型的大象圖示,然後點擊該圖示。

5ef40c7a719077a0.png

您已經匯入機器學習套件,可以開始使用圖片標籤功能了。

接下來,您必須建立簡單的使用者介面以呈現圖片,並提供一個按鈕,當使用者按下按鈕時,機器學習套件就會叫用圖片標籤模型,以剖析圖片的內容。

4. 建構使用者介面

在 Android Studio 中,您可以透過 xml 版面配置檔案編輯每個畫面 (或活動) 的使用者介面。您建立的基本應用程式只有一項活動 (代碼位於 MainActivity 且即將顯示),而且使用者介面宣告位於 activity_main.xml

您可以在 Android 專案探索工具的 res >Layout 資料夾中找到該檔案,如下所示:

3ed772e9563061e9.png

這會開啟完整的編輯器,讓您設計活動使用者介面。有很多東西,這個研究室並不是用來教導如何使用。如要進一步瞭解版面配置編輯器,請參閱:https://developer.android.com/studio/write/layout-editor

設定實驗時,請選取編輯器右上角的程式碼工具。

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 應用程式中的方法之一,可將這些檔案新增為會編譯至應用程式的資產。為了讓應用程式保持精簡,我們這麼做是為了加入一些花卉圖片。之後,您可以延展這個應用程式以使用 CameraX 或其他程式庫拍照和使用。但為了方便起見,我們現在只會幫您組合圖片。

  1. 在專案多層檢視中,在頂端的 [應用程式] 上按一下滑鼠右鍵,然後選取 [新增目錄]。
  2. 在隨即顯示的對話方塊中,列出列出不同目錄的對話方塊,然後選取 [src/main/assets]

c93650ea68bb60e9.png

完成這個步驟後,專案多層檢視中就會顯示一個新的 assets 資料夾:

444b4afab73433b8.png

  1. 在這個資料夾上按一下滑鼠右鍵,即可看到內含選項清單的彈出式視窗。其中一個選項就是在檔案系統中開啟資料夾。找出您的作業系統適用的選項,並予以選取。(在 Mac 上,這會是「在 Finder 中顯示」;在 Windows 中則是 在 Explorer 中開啟,在 Ubuntu 中則為 在「檔案」中顯示)。

95e0eca881d35f6b.png

  1. 將檔案複製到該檔案。您可以從 Pixabay 等網站下載圖片。建議將圖片重新命名為簡易。在這個範例中,圖片已重新命名為 flower1.jpg

完成這個步驟後,請返回 Android Studio,您應該會在資產資料夾內看見檔案。

cfa53c9c75a033d8.png

現在可以為這張圖片加上標籤了!

6. 撰寫分類代碼以為圖片加上標籤

(現在大家都一直在等候,我們在 Android 上進行電腦視覺技術了!)

  1. 您將在 MainActivity 檔案中編寫程式碼,因此請在 com.google.devrel.imageclassifierstep1 (或您選擇其他命名空間的名稱中) 的專案專案中尋找該程式碼。請注意,在 Android Studio 專案中,一般會設定 3 個命名空間資料夾,一個用於應用程式、一個 Android 測試和一個測試用。你會在方括號中加上 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 ,因此第一行會使用 Layout 物件建立名為 img 的實例例項。這項功能會使用內建的 Android 函式 findViewById。然後再使用檔案名稱 flower1.jpg,使用您在前一個步驟建立的 assetsToBitmap 函式從素材資源資料夾載入圖片。最後,它使用點陣圖抽象類別將點陣圖載入到 img。
  3. 版面配置檔案內含 TextView,可用於轉譯系統為圖片推測出的標籤。取得該程式碼的程式碼物件。緊接在前一個程式碼的下方:
val txtOutput : TextView = findViewById(R.id.txtOutput)

如先前所述,這會使用文字名稱尋找文字檢視的版面配置檔案資訊 (請檢查 XML 中名為 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's 標籤人員時,第一步通常是建立 Options 物件以自訂行為。並將圖片轉換為 ML 套件可辨識的 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。InputImage 是機器學習套件在處理圖片時想要採用的格式。
  • 最後,標籤人員會處理圖片,並在成功或失敗時,進行非同步回呼。如果推論成功,回呼會包含標籤清單。接著,您可以剖析這個標籤清單,以讀取標籤文字和可信度值。如果要求失敗,系統會傳送例外狀況,以便您向使用者回報。

這樣就完成了!你現在可以在 Android 裝置或模擬器上執行應用程式。如果你從未使用過這個應用程式,請參閱這篇文章:https://developer.android.com/studio/run/emulator

這裡是模擬器中的應用程式。一開始你會看到圖片和按鈕,而標籤會留空。

c07f5f307f070dc7.png

按下該按鈕後,您就會收到一組圖片標籤。

550ccaa783363551.png

如圖所示,標籤人員判定圖片含有花瓣、花朵、植物和天空的機率很高。這些全都是正確的,且都示範了模型正試著剖析圖片。

但目前還沒有判斷,這是假報的相片。為了達到這個目的,您需要以特定花卉訓練而成的自訂模型,然後在下一個研究室中學習如何進行。

在接下來的步驟中,您將探討如何在 iOS 上建構同一個應用程式。

7. 在 iOS 上建立圖片分類程式 - 開始使用

您可以在 iOS 上使用 Xcode 建立類似的應用程式。

  1. 啟動 Xcode,然後從檔案選單中選取 [New Project] (新增專案)。您會看到此對話方塊:

8fb0e6a9d6ac275e.png

  1. 選取顯示的 [App] (應用程式),然後點選 [Next] (下一步)。我們會要求您選擇專案選項。輸入名稱和機構 ID (如圖所示)。確認介面類型為 Storyboard,而且語言為 Swift,如圖所示。

76c6bdb5aee7659c.png

  1. 如果想要部署手機並設定開發人員設定檔,您可以調整小組設定。如果沒有,請保留 [無],然後使用 iOS 模擬工具執行應用程式。
  2. 點選 [下一步],然後選取要用來儲存專案和其中檔案的資料夾。請記住這項專案的位置,下一個步驟將會用到。
  3. 您接下來必須關閉 Xcode,因為在下一個步驟之後,您將使用另一個工作區檔案重新開啟檔案。

8. 使用 Cocoapods 整合機器學習套件

機器學習套件在 iOS 上也可使用,因此您可以透過非常類似的方式來建構圖片分類程式。如要進行整合,請使用 CocoaPods。如果您還沒有安裝這個應用程式,請前往 https://cocoapods.org/

  1. 開啟您建立專案的目錄。檔案應包含您的 .xcodeproj 檔案。

這裡會顯示指定 I.#39;m 的 .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 就會以原始專案和外部依附元件啟動。

32090e0024b6b5ef.png

現在您準備進行下一個步驟,並建立使用者介面了。

9. 使用分鏡腳本建立 iOS UI

  1. 開啟 Main.storyboard 檔案,就可以看到使用者介面設計和手機的設計介面。
  2. 您可以使用畫面右上方的 [+] 按鈕新增控制項。按一下該圖示即可顯示控制項調色盤。

e63bc3bafa54cc21.png

  1. 然後從這裡將 ImageViewButtonLabel 拖曳到設計表面。請按照順序由上往上排列:

f9dfc55616b25f11.png

  1. 按兩下按鈕,即可將文字從「按鈕」變更為「分類」
  2. 拖曳控點周圍的控點即可放大標籤。(假設寬度與 UIImageView 的寬度和高度的兩倍相同)。
  3. 選取標籤後,按一下右上方的 [選取工具] 按鈕,即可顯示檢查器調色盤。
  4. 完成上述操作後,請找到「Lines」設定,並確認此設定已設為 0。讓標籤呈現動態的行數。

a39708b320b56b30.png

現在您已經準備好進行下一個步驟,也就是透過插座和動作,將使用者介面進行程式碼調用。

10. 建立動作和插座

使用分鏡腳本執行 iOS 開發作業時,您需使用插座參照控制項的版面配置資訊,並定義程式碼,供使用者透過動作執行控制項時要執行的程式碼。

在下一個步驟中,您需要為 ImageView 和 Label 建立插座。系統會在程式碼中參照 ImageView 以載入圖片。此程式碼會參照程式碼,以根據機器學習套件傳回的推論設定其文字。

  1. 按一下畫面右上方的控制項,關閉旁邊的檢查工具調色盤,然後點選下方的 [新增編輯器] 按鈕。

77255f7d6284750.png

  1. 你可能會使用令人感到困惑的螢幕版面配置,因為 main.storyboard 會開啟兩次。在左側的專案導覽工具中,選取 [ViewController.swift] 開啟檢視控制器程式碼。您的設計介面似乎已從左側的分鏡腳本編輯中消失,但請別擔心,問題仍然存在!
  2. 若要恢復顯示,請按一下「查看控制器場景」中的 [查看控制器]。您可以嘗試讓 UI 看起來像下面這樣,左邊是分鏡腳本展示您的設計,而右邊是 ViewController.swift 的程式碼。

7eb21c7f9d43c9bc.png

  1. 選取左側設計表面的 UIImageView,接著按下 Ctrl 鍵,並拖曳到右側的程式碼中,將標記拖曳至 class 關鍵字正下方 (位於上方螢幕擷取畫面中的第 11 行)。

拖曳時會看到箭頭,而且拖放後也會看到如下的彈出式視窗:

37477f0611948318.png

  1. 將「Name」(名稱) 欄位填入「"imageView") 並點擊 [連結]
  2. 對標籤重複此步驟,並為它命名「lblOutput」。
  3. 重要事項:在按鈕上,您必須執行同樣的操作,但請務必將連線類型設為 [動作] 而非 [結束]

7281b6eea9fb6c23.png

  1. 將名稱命名為「doClassification」,然後按一下 [連線]。

完成後,您的程式碼看起來應該會像這樣:(請注意,標籤和圖片檢視會宣告為 IBOutlet (介面建立工具離開介面),而按鈕則是 IBAction (介面製作工具動作)。)

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 左側的多層檢視。當您捨棄圖示後,系統會顯示如下彈出式視窗:

889ff33eaec785ec.png

  1. 確認 [加到目標] 部分中的核取方塊已勾選顯示,然後按一下 [完成]

系統會將檔案與應用程式整合,方便您為檔案進行分類。您現在可以將使用者介面的程式碼做成圖片分類!

11. 撰寫圖片分類的程式碼

現在已經完成所有設定,編寫程式碼進行圖片分類的程序非常簡單。

  1. 首先,請按一下設計介面左上角的 [X],關閉分鏡腳本設計工具。這樣一來,您就能專心處理程式碼。您將為 View 的其餘部分編輯 ViewController.swift。
  2. 匯入 MLKitVision 和 MLKit ImageLabeling 程式庫,方法是在 UI 的匯入介面正下方加入下列程式碼:
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。機器學習套件在執行圖片分類時會使用這種類型。因此,在 getLabel 基金中,加入以下程式碼:
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 成員,請不用擔心。您還沒實作完這個程式,接下來就要完成。

為了方便您起見,以下提供完整的 GetLabel 基金:

// 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

建立動作時,所有動作都已完成,因此您只需更新先前建立的 IBAction (呼叫 doClassificaiton),即可呼叫 getLabels

以下程式碼是用 imageView 的內容呼叫此程式碼:

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

現在就開始執行應用程式吧!你可以在這裡查看這項動作的實際運作情形:

eb8e6c1b2e2c65e0.png

請注意,版面配置可能會因裝置而異。

這個程式碼研究室並未針對各種裝置探索不同的版面配置類型,這本身也十分複雜。如果系統並未顯示使用者介面,請返回分鏡腳本編輯器,畫面底部會顯示「檢視身分:」部分,讓您挑選特定裝置。選擇與您要測試的圖片或裝置相符的項目,並配合使用者介面進行修改。

隨著您逐漸瞭解 iOS 開發流程,您將會學習如何使用限制條件來確保使用者介面在不同手機上都是一致的,但這不在本研究室的範圍之內。

12. 恭喜!

您已經在 Android 和 iOS 中導入了某個應用程式,可透過一般模型提供基本的電腦視覺。您已完成大部分繁重的操作。

在下一代程式碼研究室中,您將建構一個可辨識不同類型的花卉的自訂模型,而且只需要幾行程式碼,就能在這個應用程式中導入自訂模型,使其更加實用!