Crea la tua prima app di visione artificiale su Android o iOS

1. Prima di iniziare

In questo codelab esplorerai come creare un'app che gestisce il caso d'uso principale di Computer Vision, rilevando i contenuti principali di un'immagine. Questa operazione viene in genere chiamata classificazione delle immagini o etichettatura delle immagini.

Prerequisiti

Questo codelab fa parte del percorso Inizia a utilizzare la classificazione delle immagini. È stato scritto per sviluppatori esperti nuovi nel machine learning.

Cosa devi creare

  • Un'app Android in grado di classificare l'immagine di un fiore
  • (Facoltativo) Un'app per iOS in grado di classificare l'immagine di un fiore

Che cosa ti serve

  • Android Studio, disponibile all'indirizzo https://developer.android.com/studio per la sezione Android del codelab
  • Xcode, disponibile nell'App Store di Apple, per la parte iOS del codelab

2. Inizia

Computer Vision è un campo nella più ampia disciplina del machine learning, che si occupa di trovare nuovi modi con cui le macchine possono elaborare ed estrarre informazioni dai contenuti di un'immagine. Se prima un computer memorizzava solo i dati effettivi delle immagini, come i valori dei pixel che lo compongono, Computer Vision consente a un computer di analizzare i contenuti dell'immagine e ottenere informazioni su ciò che contiene.

Ad esempio, nel campo della visione artificiale un'immagine di un gatto potrebbe essere etichettata come contenente un gatto, oltre ai pixel che compongono quell'immagine. Esistono altri campi della visione artificiale che esaminano più in dettaglio questo aspetto, come Rilevamento di oggetti, in cui il computer è in grado di individuare più elementi in un'immagine e ricavarne riquadri di delimitazione.

In questo codelab, scoprirai come creare un'app che gestisca il caso d'uso principale, rilevando i contenuti principali dell'immagine. Questa operazione viene in genere chiamata classificazione delle immagini o etichettatura delle immagini.

Per semplificare al massimo l'app, verranno utilizzate le immagini associate come risorse e verrà visualizzata una classificazione al loro interno. Le estensioni future potrebbero essere l'uso di un selettore di immagini o il pull di immagini direttamente dalla fotocamera.

Inizierai la procedura di creazione dell'app su Android utilizzando Android Studio. Vai al passaggio 7 per eseguire l'equivalente su iOS.

  1. Apri Android Studio, vai al menu File e seleziona Crea un nuovo progetto.
  2. Ti verrà chiesto di scegliere un modello di progetto. Seleziona Attività vuota.

859b1875e37c321a.png

  1. Tocca Avanti. Ti verrà chiesto di configurare il progetto. Assegnagli il nome e il pacchetto che preferisci, ma il codice campione in questo codelab utilizzerà il nome progetto ProjectClassifierStep1 e il nome pacchetto com.google.imageclassifierstep1.

ee3b6a81bad87b3.png

  1. Scegli il tuo linguaggio preferito, Kotlin o Java. Questo lab utilizza Kotlin, quindi se vuoi esattamente seguire i tuoi suggerimenti, probabilmente sceglierai Kotlin.
  2. Al termine, fai clic su Fine. Android Studio creerà l'app per te. Potrebbe essere necessario qualche istante per configurare tutto.

3. Importa libreria di etichettatura delle immagini ML Kit

ML Kit (https://developers.google.com/ml-kit) offre diverse soluzioni per sviluppatori, che rispondono a scenari comuni nel machine learning, semplificando l'implementazione e il lavoro multipiattaforma. ML Kit fornisce una libreria chiavi in mano che puoi utilizzare in questa app chiamata Image Labeling. Questa libreria include un modello preaddestrato a riconoscere oltre 600 classi di immagini. Pertanto, è perfetto per iniziare.

Tieni presente che il ML Kit ti consente anche di utilizzare modelli personalizzati utilizzando la stessa API, così, quando è tutto pronto, puoi andare oltre "iniziando" e iniziare a creare la tua app di etichettatura delle immagini personalizzata che utilizza un modello addestrato per il tuo scenario.

In questo scenario, creerai un riconoscimento floreale. Quando crei la tua prima app e visualizzi l'immagine di un fiore, viene riconosciuta come tale. In seguito, quando creerai il tuo modello di rilevatore di fiori, potrai rilasciarlo nella tua app con modifiche minime grazie al ML Kit e fare in modo che il nuovo modello ti dica di che tipo di fiore si tratta, ad esempio un tulipano o una rosa.

  1. In Android Studio, utilizzando lo strumento Esplorazione progetto, assicurati che sia selezionato Android in alto.
  2. Apri la cartella Gradle Scripts e seleziona il file build.gradle per l'app. Potrebbero esserci due o più livelli, quindi assicurati di utilizzare quello di app come mostrato di seguito:

93c2e157136671aa.png

  1. Nella parte inferiore del file è presente una sezione denominata dependencies in cui è archiviato un elenco di impostazioni implementation, testImplementation e androidImplementation. Aggiungine una nuova nel file con questo codice:
implementation 'com.google.mlkit:image-labeling:17.0.3'

Assicurati che sia incluso nelle dipendenze { }

  1. Nella parte superiore della finestra viene visualizzata una barra che indica che l'elemento build.gradle è cambiato e devi ripetere la sincronizzazione. Vai avanti. Se non la vedi, cerca l'icona a forma di elefante sulla barra degli strumenti in alto a destra e fai clic.

5ef40c7a719077a0.png

Hai importato il ML Kit e sei pronto per iniziare l'etichettatura delle immagini.

In seguito, creerai un'interfaccia utente semplice per eseguire il rendering di un'immagine e visualizzerai un pulsante che quando l'utente preme, ML Kit richiama il modello del labeler immagine per analizzare i contenuti dell'immagine.

4. Crea l'interfaccia utente

In Android Studio, puoi modificare l'interfaccia utente per ogni schermata (o attività) utilizzando un file di layout basato su XML. L'app di base che hai creato ha una singola attività (il cui codice è in MainActivity e lo vedrai a breve) e la dichiarazione dell'interfaccia utente è in activity_main.xml.

Puoi trovarlo nella cartella res > layout in Explorer per progetti di Android, in questo modo:

3ed772e9563061e9.png

Si aprirà un editor completo che ti consentirà di progettare l'interfaccia utente di attività. C'è molto lì, e non c'è intenzione di questo lab di spiegarti come usarlo. Per saperne di più sull'editor di layout, consulta: https://developer.android.com/studio/write/layout-editor

Ai fini di questo lab, seleziona lo strumento Codice nell'angolo in alto a destra dell'editor.

1f7dbdef48d9ade6.png

Nella parte principale della finestra ora vedrai solo il codice XML. Modifica il codice nel seguente modo:

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

In questo modo, avrai un layout semplicissimo contenente ImageView (per visualizzare l'immagine), Button (da premere) e TextView in cui verranno visualizzate le etichette.

Ora hai definito l'interfaccia utente. Prima di iniziare la programmazione, aggiungi alcune immagini come asset e l'app si baserà su queste immagini.

5. Raggruppa immagini con l'app

Un modo per raggruppare file aggiuntivi con un'app Android è aggiungerli come asset che vengono compilati all'interno dell'app. Per semplificare questa app, possiamo aggiungere un'immagine di alcuni fiori. Successivamente, puoi estendere questa app per utilizzare CameraX o altre librerie per scattare una foto e usare la funzionalità. Per semplicità, per adesso raduniamo l'immagine.

  1. Nell'Explorer progetti, in app in alto, fai clic con il pulsante destro del mouse e seleziona Nuova directory.
  2. Nella finestra di dialogo visualizzata con un elenco diverso di directory, seleziona src/main/assets.

c93650ea68bb60e9.png

Dopo aver eseguito questa operazione, verrà visualizzata una nuova cartella assets in Explorer progetti:

444b4afab73433b8.png

  1. Fai clic con il pulsante destro del mouse su questa cartella e visualizzerai un popup con un elenco di opzioni. Una delle seguenti operazioni consiste nell'aprire la cartella nel file system. Trova quella più adatta al tuo sistema operativo e selezionala. Su Mac, l'app sarà Reveal in Finder, su Windows sarà Apri in Esplora file, mentre su Ubuntu sarà Mostra in file.

95e0eca881d35f6b.png

  1. Copia un file al suo interno. Puoi scaricare immagini da siti come Pixabay. Ti consigliamo di rinominare l'immagine in qualcosa di semplice. In questo caso, l'immagine è stata rinominata flower1.jpg.

Al termine dell'operazione, torna ad Android Studio e dovresti vedere il file nella cartella degli asset.

cfa53c9c75a033d8.png

Sei pronto per etichettare questa immagine!

6. Scrivere il codice di classificazione per etichettare l'immagine

E ora la parte che tutti aspettavamo, ovvero Computer Vision su Android!

  1. Scrivi il codice nel file MainActivity, quindi cercalo nella cartella del progetto in com.google.devrel.imageclassifierstep1 (o nel tuo spazio dei nomi equivalente se ne scegli uno diverso). Tieni presente che in un progetto Android Studio sono generalmente configurati tre spazi dei nomi, uno per l'app, uno per Android Test e uno per il test. Troverai il tuo MainActivity in quello in cui non è presente una descrizione che lo segue tra parentesi.

b5aef8dd5e26b6c2.png

Se hai scelto di utilizzare Kotlin, ti starai chiedendo perché la cartella principale è denominata Java. È un artefatto storico, a partire dal momento in cui Android Studio era unicamente Java. Le versioni future potrebbero risolvere il problema, ma non ti preoccupare se vuoi utilizzare Kotlin, non è un problema. È solo il nome della cartella del codice sorgente.

  1. Apri il file MainActivity e nell'editor di codice vedrai un file del corso chiamato MainActivity. Dovrebbe avere questo aspetto:
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

Sotto la parentesi graffa chiusa, puoi aggiungere un codice estensione che non fa parte della classe, ma può essere utilizzato dalla classe. Avrai bisogno di un'estensione per leggere un file dalle risorse come bitmap. Verrà utilizzata per caricare l'immagine precedentemente copiata nella cartella degli asset.

  1. Aggiungi questo codice:
// 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 probabilmente si lamenterà a questo punto, evidenziando parte del codice in rosso, come Context, Bitmap e IOException:

d2bde17e3c04aeed.png

Non preoccuparti. Il motivo è che non hai ancora importato le librerie che le contengono. Android Studio offre una pratica scorciatoia.

  1. Trascina il cursore sulla parola e premi Alt + Invio (Opzione + Invio su un Mac) per generare automaticamente l'importazione.
  2. Successivamente, puoi caricare la bitmap dagli asset e inserirla in ImageView. Torna alla onCreateFunction dell'attività principale e aggiungi questo codice sotto la riga 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. Come in precedenza, una parte del codice viene evidenziata in rosso. Posiziona il cursore sulla riga e utilizza Alt + Invio / Opzione + Invio per aggiungere automaticamente le importazioni.
  2. Nel file layout.xml che hai creato in precedenza, hai assegnato a ImageView il nome imageToLabel, quindi la prima riga creerà un'istanza di un oggetto ImageView, chiamato img, utilizzando tali informazioni di layout. Trova i dettagli utilizzando findViewById, una funzione Android integrata. Quindi utilizza il nome file flower1.jpg per caricare un'immagine dalla cartella degli asset utilizzando la funzione assetsToBitmap che hai creato nel passaggio precedente. Infine, utilizza la classe astratta bitmap per caricare la bitmap in img.
  3. Il file di layout aveva un TextText che verrà utilizzato per visualizzare le etichette dedotte per l'immagine. Ottieni un oggetto di codice per il prossimo. Subito sotto il codice precedente, aggiungi questo:
val txtOutput : TextView = findViewById(R.id.txtOutput)

Come prima, trova le informazioni sul file di layout per la visualizzazione di testo utilizzando il suo nome (controlla il codice XML dove si chiama txtOutput) e le utilizza per creare un'istanza di un oggetto TextView chiamato txtOutput.

Allo stesso modo, creerai un oggetto pulsante per rappresentare il pulsante e lo creerai un'istanza con i contenuti del file di layout.

Nel file di layout abbiamo chiamato il pulsante btnTest, in modo da poter creare un'istanza in questo modo:

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

Ora che hai tutto il codice e i controlli inizializzati, il passaggio successivo (e finale) consiste nel utilizzarli per ottenere un'inferenza sull'immagine.

Prima di continuare, assicurati che il tuo codice onCreate abbia il seguente aspetto:

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)
}

Nessuna delle parole chiave deve essere di colore rosso, per indicare che non sono ancora state importate. In caso contrario, torna indietro ed esegui il trucco ALT + INVIO per generare le importazioni.

Quando utilizzi l'etichettatore di immagini di ML Kit, il primo passaggio consiste solitamente nella creazione di un oggetto Options per personalizzare il comportamento. Convertirai la tua immagine in un formato InputImage che possa essere riconosciuto da ML Kit. Quindi crei un oggetto Labeler per eseguire l'inferenza. Riceverai una chiamata asincrona con i risultati, che potrai poi analizzare.

Fai clic sul pulsante che hai creato all'interno dell'evento onClickListener dell'evento. Ecco il codice completo:

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
  }
}
  • Quando l'utente fa clic sul pulsante, il codice crea un'istanza di un labeler utilizzando ImageLabeling.getClient, passandolo su ImageLabelerOptions. Questa proprietà è dotata di una proprietà DEFAULT_OPTIONS che ci consente di essere operativi in poco tempo.
  • Verrà quindi creata un'immagine di input dalla bitmap utilizzando il suo metodo fromBitmap. InputImage è il formato desiderato di ML Kit per l'elaborazione delle immagini.
  • Infine, il labeler elaborerà l'immagine e fornirà un callback asincrono, in caso di esito positivo o negativo. Se l'inferenza ha esito positivo, il callback includerà un elenco di etichette. Puoi quindi analizzare questo elenco di etichette per leggere il testo dell'etichetta e il valore di affidabilità. In caso contrario, ti verrà inviata un'eccezione che potrai utilizzare per segnalare l'utente.

e il gioco è fatto. Ora puoi eseguire l'app su un dispositivo Android o all'interno dell'emulatore. Se non l'hai mai fatto prima, scopri come: https://developer.android.com/studio/run/emulator

Ecco l'app in esecuzione nell'emulatore. All'inizio vedrai l'immagine, il pulsante e l'etichetta sarà vuota.

c07f5f307f070dc7.png

Premi il pulsante per ottenere una serie di etichette per l'immagine.

550ccaa783363551.png

Qui puoi vedere che l'etichettatore ha stabilito che vi erano alte probabilità che l'immagine conteneva un petalo, un fiore, una pianta e il cielo. Tutti questi valori sono corretti e dimostrano che il modello funziona per analizzare l'immagine.

Ma non può ancora determinare che questa sia l'immagine di una margherita. Per questo avrai bisogno di un modello personalizzato addestrato su fiori specifici e imparerai come farlo nel prossimo lab.

Nei passaggi seguenti, scoprirai come creare questa stessa app su iOS.

7. Creare un classificatore di immagini su iOS - Iniziare

Puoi creare un'app simile su iOS utilizzando Xcode.

  1. Avvia Xcode e seleziona New Project dal menu file. Vedrai questa finestra di dialogo:

8fb0e6a9d6ac275e.png

  1. Seleziona App come mostrato e fai clic su Avanti. Ti verrà chiesto di scegliere delle opzioni per il tuo progetto. Assegna un nome e un identificatore dell'organizzazione, come mostrato. Assicurati che il tipo di interfaccia sia Storyboard e che la lingua sia Swift come mostrato.

76c6bdb5aee7659c.png

  1. Se vuoi eseguire il deployment sul telefono e hai configurato un profilo sviluppatore, puoi configurare le impostazioni del team. In caso contrario, lascialo su Nessuno e puoi usare il simulatore di iOS per eseguire l'app.
  2. Fai clic su Avanti e seleziona una cartella in cui archiviare il progetto e i relativi file. Ricorda la posizione di questo progetto, ti servirà nel passaggio successivo.
  3. Per ora, chiudi Xcode perché, dopo il passaggio successivo, lo riaprirai utilizzando un file di area di lavoro diverso.

8. Integra il ML Kit utilizzando Cocoapods

Poiché ML Kit funziona anche su iOS, puoi usarlo in un modo molto simile per creare una categoria di classificazione delle immagini. Per integrarlo, dovrai utilizzare CocoaPods. Se non l'hai ancora installato, puoi farlo seguendo le istruzioni riportate all'indirizzo https://cocoapods.org/.

  1. Apri la directory in cui hai creato il progetto. Deve contenere il file .xcodeproj.

Qui puoi vedere il file .xcodeproj che indica I'm nella posizione corretta.

e2966a47e84eb398.png

  1. In questa cartella, crea un nuovo file denominato Podfile. Non c'è estensione, è solo Podfile. Al suo interno, aggiungi quanto segue:
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabeling'
end
  1. Salvalo e torna al terminale. Nello stesso tipo di directory pod install. Cocoapods scaricherà le librerie e le dipendenze appropriate e creerà un nuovo spazio di lavoro che combina il tuo progetto con le sue dipendenze esterne.

3b4c628b0cbface8.png

Tieni presente che alla fine ti chiede di chiudere le sessioni Xcode e di utilizzare il file Workspace da questo momento in poi. Apri questo file e Xcode verrà avviato con il tuo progetto originale più le dipendenze esterne.

32090e0024b6b5ef.png

A questo punto puoi passare al passaggio successivo e creare l'interfaccia utente.

9. Creare l'interfaccia utente di iOS usando gli Storyboard

  1. Apri il file Main.storyboard e vedrai un layout dell'interfaccia utente con una superficie di progettazione per un telefono.
  2. In alto a destra dello schermo c'è un pulsante + che puoi utilizzare per aggiungere controlli. Fai clic sull'icona per accedere alla tavolozza dei controlli.

e63bc3bafa54cc21.png

  1. Da qui, trascina un elemento ImageView, un pulsante e un'etichetta sulla superficie di progettazione. Disponile dall'alto verso il basso come mostrato:

f9dfc55616b25f11.png

  1. Fai doppio clic sul pulsante per modificare il testo da Pulsante a Classifica.
  2. Trascina i punti di manipolazione di controllo intorno all'etichetta per ingrandirla. Di' circa la stessa larghezza di UIImageView e il doppio dell'altezza.
  3. Con l'etichetta ancora selezionata, fai clic sul pulsante selettori in alto a destra per visualizzare la tavolozza degli ispettori.
  4. Dopo aver eseguito questa operazione, individua l'impostazione Righe e assicurati che sia impostata su 0. Ciò consente all'etichetta di visualizzare un numero dinamico di righe.

a39708b320b56b30.png

Ora puoi svolgere il passaggio successivo: collegare l'interfaccia utente al codice per utilizzare i punti di accesso e le azioni.

10. Crea azioni e prese

Durante lo sviluppo di iOS utilizzando gli storyboard, fai riferimento alle informazioni sul layout dei controlli utilizzando gli outlet e definisci il codice da eseguire quando l'utente esegue un'azione su un controllo utilizzando le azioni.

Nel passaggio successivo dovrai creare dei punti di partenza per ImageView ed Label. L'immagine viene chiamata nel codice per caricarla. L'etichetta vi farà riferimento nel codice per impostare il testo in base all'inferenza che proviene da ML Kit.

  1. Chiudi la tavolozza degli controllori facendo clic sul controllo in alto a destra dello schermo, quindi fai clic sul pulsante Aggiungi editor a destra immediatamente sotto.

77255f7d6284750.png

  1. Avrai a disposizione un layout dello schermo poco chiaro in cui la scheda principale.storyboard viene aperta due volte. A sinistra, nel progetto di navigazione del progetto, seleziona ViewController.swift in modo che il codice del controller di visualizzazione si apra. Sembra che la superficie del design sia scomparsa dall'editor di storyboard a sinistra, ma non preoccuparti, è ancora lì!
  2. Per riaverlo, fai clic su Visualizza controller nella scena del controller. Fai in modo che l'interfaccia utente abbia il seguente aspetto: con lo storyboard a sinistra che mostra il design e il codice per ViewController.swift sulla destra.

7eb21c7f9d43c9bc.png

  1. Seleziona UIImageView dalla superficie di progettazione a sinistra e, premendo il tasto CTRL, trascina il codice a destra e rilascialo appena sotto la parola chiave class (nella riga 11 nello screenshot in alto).

Vedrai una freccia che trascini e quando rilasci il pulsante, viene visualizzato un popup come questo:

37477f0611948318.png

  1. Compila il campo Nome come "imageView" e fai clic su Connect (Connetti).
  2. Ripeti questo processo con l'etichetta e assegnale il nome "quobl;lblOutput"."
  3. Importante: anche se utilizzi il pulsante, stai svolgendo la stessa operazione, ma assicurati di impostare il tipo di connessione su Azione e non su Outlet.

7281b6eea9fb6c23.png

  1. Assegna il nome "Classificazione" e fai clic su Connetti.

Al termine, il codice dovrebbe avere questo aspetto: (tieni presente che la visualizzazione dell'etichetta e dell'immagine è dichiarata come IBOutlet (outlet Interface Builder) e il pulsante come IBAction (azione Interface Builder).

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. Infine, combina un'immagine con l'app per consentirci di effettuare facilmente la classificazione. Per farlo, trascina il file da Esplora file in Esplorazione a sinistra di Xcode. Quando lo rilasci, viene visualizzato un popup come questo:

889ff33eaec785ec.png

  1. Assicurati che la casella di controllo nella sezione Aggiungi a target sia selezionata, quindi fai clic su Fine.

Il file verrà fornito in bundle con l'app e ora potrai classificarlo facilmente. Ora puoi programmare l'interfaccia utente per eseguire la classificazione delle immagini.

11. Scrivere il codice per la classificazione delle immagini

Ora che hai configurato tutto, scrivere il codice per eseguire la classificazione delle immagini è molto semplice.

  1. Per iniziare, chiudi il designer dello storyboard facendo clic su X nell'angolo in alto a sinistra sopra la superficie del progetto. In questo modo puoi concentrarti solo sul codice. Dovrai modificare ViewController.swift per il resto di questo lab.
  2. Importa le librerie MLKitVision e MLKit ImageLabeling aggiungendo questo codice in alto, subito sotto l'importazione di UIKit:
import MLKitVision
import MLKitImageLabeling
  1. Successivamente, all'interno della funzione viewDidLoad, inizializza ImageView utilizzando il file che abbiamo raccolto nell'app:
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    imageView.image = UIImage(named:"flower1.jpg")
}
  1. Crea una funzione helper per ottenere le etichette per l'immagine, immediatamente sotto il viewDidLoad():
func getLabels(with image: UIImage){
  1. Crea un'immagine Vision a partire dall'immagine. ML Kit utilizza questo tipo quando esegue la classificazione delle immagini. Quindi, all'interno della funzione getLabels, aggiungi questo codice:
let visionImage = VisionImage(image: image)
visionImage.orientation = image.imageOrientation
  1. Quindi crea le opzioni per il labeler immagini. Verrà inizializzata utilizzando queste opzioni. In questo caso, devi solo impostare un'opzione di base per confidenceThreshold. Ciò significa che chiederai solo all'etichettatore di restituire le etichette con un grado di confidenza pari o superiore a 0,4. Ad esempio, per il nostro fiore, classi come "pianta" o "petalo" avranno un'elevata affidabilità, ma quelle come "pallacanestro" o "auto" ne avranno una bassa.
let options = ImageLabelerOptions()
options.confidenceThreshold = 0.4
  1. Ora crea il labeler utilizzando queste opzioni:
let labeler = ImageLabeler.imageLabeler(options: options)
  1. Una volta trovato, puoi elaborarlo. Ti fornirà un callback asincrono con etichette (se l'operazione è andata a buon fine) ed errore (se non è riuscito), dopodiché potrai elaborare un'altra funzione che creeremo in un attimo.
labeler.process(visionImage) { labels, error in
    self.processResult(from: labels, error: error)
  }

Non preoccuparti se Xcode segnala che non è presente alcun membro di processResult. Non hai ancora implementato questo comando e dovrai farlo ora.

Per praticità, ecco la pagina completa di 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)
 }
}

Ora devi implementare la funzione processResult. Questo è molto semplice poiché abbiamo etichette e un oggetto errore. Le etichette devono essere trasmesse nel tipo ImageLabel da Kit ML.

Dopo aver eseguito questa operazione, puoi semplicemente iterare l'insieme di etichette, estrarre la descrizione e il valore di affidabilità e aggiungerli a un elemento var chiamato labeltexts. Dopo aver eseguito l'iterazione di tutti questi valori, è sufficiente impostare lblOutput.text su tale valore.

Ecco la funzione completa:

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

Resta solo da chiamare getLabels quando l'utente preme il pulsante.

Quando hai creato l'azione, tutto è stato cablato per te, quindi devi solo aggiornare il dispositivo IBAction chiamato doClassificaiton creato in precedenza per chiamare getLabels.

Ecco il codice da chiamare con i contenuti di imageView:

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

Ora esegui la tua app e prova. Puoi vedere la regola in azione qui:

eb8e6c1b2e2c65e0.png

Tieni presente che il layout potrebbe avere un aspetto diverso a seconda del dispositivo.

Il codelab non esplora diversi tipi di layout per dispositivo e si tratta di un concetto piuttosto complesso. Se non vedi l'interfaccia utente correttamente, torna all'editor dello storyboard e, in fondo, vedrai una sezione Visualizza come:, dove puoi scegliere un dispositivo specifico. Scegline una che corrisponda all'immagine o al dispositivo su cui stai eseguendo il test e modifica la UI in base alle tue esigenze.

Man mano che approfondisci lo sviluppo di iOS, imparerai a utilizzare i vincoli per assicurarti che l'interfaccia utente sia coerente per tutti i telefoni, ma questo non rientra nell'ambito di questo lab.

12. Complimenti!

Hai implementato un'app sia su Android che su iOS che ti offre la visione artificiale di base con un modello generico. Hai già fatto la maggior parte del lavoro pesante.

Nel prossimo codelab, creerai un modello personalizzato che riconosce diversi tipi di fiori e con poche righe di codice potrai implementare il modello personalizzato in questa app per renderlo più utile.