Con i progressi tecnologici, siamo al punto in cui i nostri dispositivi possono utilizzare le loro fotocamere integrate per identificare e etichettare con precisione le immagini utilizzando un set di dati pre-formato. Puoi anche formare i tuoi modelli, ma in questo tutorial utilizzeremo un modello open source per creare un'app per la classificazione delle immagini.
Ti mostrerò come creare un'app in grado di identificare le immagini. Inizieremo con un progetto Xcode vuoto e implementeremo il riconoscimento delle immagini basato sull'apprendimento automatico un passo alla volta.
Prima di iniziare, assicurati di avere l'ultima versione di Xcode installata sul tuo Mac. Questo è molto importante perché Core ML sarà disponibile solo su Xcode 9 o versioni successive. Puoi verificare la tua versione aprendo Xcode e andando a Xcode > Informazioni su Xcode nella barra degli strumenti superiore.
Se la tua versione di Xcode è precedente a Xcode 9, puoi andare al Mac App Store e aggiornarlo, oppure, se non ce l'hai, scaricalo gratuitamente.
Dopo esserti assicurato di avere la versione corretta di Xcode, dovrai creare un nuovo progetto Xcode.
Vai avanti e apri Xcode e fai clic Crea un nuovo progetto Xcode.
Successivamente, dovrai scegliere un modello per il tuo nuovo progetto Xcode. È piuttosto comune usare a App Single View, quindi vai avanti e selezionalo e fai clic Il prossimo.
Puoi nominare il tuo progetto come preferisci, ma nominerò il mio Classificazione delle immagini CoreML. Per questo progetto, utilizzeremo Swift, quindi assicurati che sia selezionato in linguaggio cadere in picchiata.
Poiché Xcode Simulator non ha una fotocamera, dovrai collegare il tuo iPhone. Sfortunatamente, se non hai un iPhone, dovrai prenderne uno in prestito per poter seguire questo tutorial (e per qualsiasi altra app correlata alla fotocamera). Se hai già un iPhone collegato a Xcode, puoi saltare al passaggio successivo.
Una nuova funzionalità di Xcode 9 è che puoi eseguire il debug in modalità wireless della tua app su un dispositivo, quindi prendiamoci del tempo per configurarlo ora:
Nella barra dei menu in alto, scegli Finestra > Dispositivi e simulatori.Nella finestra che appare, assicurati che dispositivi è selezionato in alto.
Ora, collega il dispositivo usando un cavo Lightning. Questo dovrebbe far apparire il tuo dispositivo nel pannello di sinistra di Dispositivi e simulatori finestra. Basta fare clic sul dispositivo e controllare Connetti via rete scatola.
Ora potrai eseguire il debug in modalità wireless su questo iPhone per tutte le app future. Per aggiungere altri dispositivi, è possibile seguire un processo simile.
Quando vuoi finalmente usare il tuo iPhone per eseguire il debug, selezionalo dal menu a discesa accanto a Correre pulsante. Dovresti vedere un'icona di rete accanto ad essa, che mostra che è connessa per il debug wireless. Ho selezionato L'iPhone di Vardhan, ma devi selezionare il tuo dispositivo specifico.
Ora che hai creato il tuo progetto e configurato il tuo iPhone come un simulatore, ci addentreremo un po 'più in profondità e inizieremo a programmare l'app di classificazione delle immagini in tempo reale.
Per poter iniziare a creare l'app di classificazione delle immagini Core ML, devi prima ottenere il modello Core ML dal sito Web di Apple. Come ho detto prima, puoi anche addestrare i tuoi modelli, ma questo richiede un processo separato. Se scorri fino in fondo al sito di apprendimento automatico di Apple, sarai in grado di scegliere e scaricare un modello.
In questo tutorial, userò il MobileNet.mlmodel modello, ma puoi usare qualsiasi modello purché tu conosca il suo nome e possa assicurarti che finisca .mlmodel.
Ci sono un paio di quadri che dovrai importare insieme al solito UIKit
. Nella parte superiore del file, assicurarsi che siano presenti le seguenti istruzioni di importazione:
import UIKit import AVKit import Vision
Avremo bisogno AVKit
perché creeremo un AVCaptureSession
per visualizzare un feed dal vivo mentre si classificano le immagini in tempo reale. Inoltre, poiché si utilizza la visione artificiale, sarà necessario importare il file Visione
struttura.
Una parte importante di questa app è la visualizzazione delle etichette dei dati di classificazione delle immagini e del feed video dal vivo dalla fotocamera del dispositivo. Per iniziare a progettare la tua interfaccia utente, vai al tuo Main.storyboard file.
Vai al Libreria di oggetti e cercare un Immagine vista. Basta trascinarlo sul View Controller per aggiungerlo. Se lo desideri, puoi anche aggiungere un'immagine segnaposto in modo da avere un'idea generale di come apparirà l'app quando viene utilizzata.
Se scegli di avere un'immagine segnaposto, assicurati che il Modalità Contenuto è impostato per Vestibilità, e tu controlli la casella che dice Clip ai limiti. In questo modo, l'immagine non apparirà allungata e non apparirà al di fuori del UIImageView
scatola.
Ecco come dovrebbe essere il tuo storyboard ora:
Indietro nel Libreria di oggetti, cerca a vista e trascinalo sul tuo View Controller. Questo servirà da sfondo per le nostre etichette in modo che non vengano nascoste nell'immagine visualizzata. Renderizzeremo questa visualizzazione traslucida in modo che parte del livello di anteprima sia ancora visibile (questo è solo un bel tocco per l'interfaccia utente dell'app).
Trascina questo nella parte inferiore dello schermo in modo che tocchi il contenitore su tre lati. Non importa quale altezza scegliamo, perché fisseremo dei limiti per questo in un solo momento qui.
Questa, forse, è la parte più importante della nostra interfaccia utente. Dobbiamo mostrare ciò che la nostra app ritiene che l'oggetto sia e quanto sia sicuro (livello di confidenza). Come probabilmente hai intuito, dovrai trascinarne due Etichetta(S)dal Libreria di oggetti alla vista che abbiamo appena creato. Trascina queste etichette da qualche parte vicino al centro, impilate l'una sull'altra.
Per l'etichetta in alto, vai al Ispettore degli attributi e fare clic su T pulsante accanto allo stile e alle dimensioni del carattere e, nel popup, selezionare Sistema come il font. Per differenziare questo dall'etichetta di fiducia, selezionare Nero come il stile. Infine, cambia il taglia a 24.
Per l'etichetta in basso, seguire gli stessi passaggi, ma invece di selezionare Nero come il stile, selezionare Regolare, e per il taglia, selezionare 17.
L'immagine sotto mostra come la tua Storyboard dovrebbe apparire quando hai aggiunto tutte queste viste ed etichette. Non preoccuparti se non sono esattamente uguali ai tuoi; aggiungeremo dei vincoli a loro nel prossimo passaggio.
Affinché questa app funzioni su diverse dimensioni dello schermo, è importante aggiungere vincoli. Questo passaggio non è cruciale per il resto dell'app, ma si consiglia vivamente di farlo in tutte le app iOS.
La prima cosa da limitare è la nostra UIImageView
. Per fare ciò, selezionare la vista dell'immagine e aprire il Menu Pin nella barra degli strumenti in basso (sembra un quadrato con i vincoli ed è il secondo da destra). Quindi, dovrai aggiungere i seguenti valori:
Prima di procedere, assicurati che il Vincola ai margini casella non è selezionata in quanto ciò creerà una lacuna tra lo schermo e la visualizzazione dell'immagine reale. Quindi, colpisci accedere.Adesso tuo UIImageView
è centrato sullo schermo e dovrebbe apparire giusto su tutte le dimensioni del dispositivo.
Ora, il prossimo passo consiste nel vincolare la vista su cui appaiono le etichette. Seleziona la vista, quindi vai al Menu Pin ancora. Aggiungi i seguenti valori:
Ora, semplicemente colpito accedere per salvare i valori. La tua vista è ora vincolata alla parte inferiore dello schermo.
Poiché la vista è ora vincolata, è possibile aggiungere vincoli alle etichette relative alla vista anziché allo schermo. Questo è utile se in seguito si decide di cambiare la posizione delle etichette o della vista.
Seleziona entrambe le etichette e mettile in una vista stack. Se non sai come fare, devi semplicemente premere il pulsante (il secondo da sinistra) che sembra una pila di libri con una freccia rivolta verso il basso. Vedrai quindi che i pulsanti diventano un oggetto selezionabile.
Fare clic sulla vista pila, quindi fare clic su Allinea menu (terzo da sinistra) e assicurarsi che le seguenti caselle siano controllate:
Adesso, colpisci accedere. Le etichette devono essere centrate nella vista dal passaggio precedente e ora appariranno uguali su tutte le dimensioni dello schermo.
L'ultimo passaggio nell'interfaccia utente sarebbe connettere gli elementi al tuo ViewController ()
classe. Basta aprire il Assistente editore e poi Control-clic e Trascinare all'interno di ogni elemento nella parte superiore della classe ViewController.swift. Ecco cosa li chiamerò in questo tutorial:
UILabel
: objectLabel
UILabel
: confidenceLabel
UIImageView
: ImageView
Certo, puoi chiamarli come vuoi, ma questi sono i nomi che troverai nel mio codice.
Il feed video live richiederà un AVCaptureSession
, quindi creiamo uno ora. Visualizzeremo anche l'input della telecamera all'utente in tempo reale. Fare una sessione di acquisizione è un processo piuttosto lungo, ed è importante capire come farlo perché sarà utile in qualsiasi altro sviluppo che fai usando la camera di bordo su uno qualsiasi dei dispositivi Apple.
Per iniziare, possiamo creare un'estensione di classe e renderla conforme al AVCaptureVideoDataOutputSampleBufferDelegate
protocollo. Puoi facilmente farlo nel reale ViewController
classe, ma stiamo usando le migliori pratiche qui in modo che il codice sia ordinato e ordinato (questo è il modo in cui lo fareste per le app di produzione).
In modo che possiamo chiamare questo dentro viewDidLoad ()
, dovremo creare una funzione chiamata setupSession ()
che non contiene alcun parametro. Puoi dare un nome a ciò che vuoi, ma ricorda il nome quando chiamiamo questo metodo più tardi.
Una volta che hai finito, il tuo codice dovrebbe apparire come il seguente:
// MARK: - Estensione AVCaptureSession ViewController: AVCaptureVideoDataOutputSampleBufferDelegate func setupSession () // Il tuo codice va qui
Il primo passo nella creazione della sessione di acquisizione è verificare se il dispositivo ha una fotocamera. In altre parole, non tentare di utilizzare la fotocamera se non ci sono telecamere. Dovremo quindi creare la sessione di acquisizione effettiva.
Aggiungi il seguente codice al tuo setupSession ()
metodo:
guard let device = AVCaptureDevice.default (per: .video) else return guard let input = try? AVCaptureDeviceInput (dispositivo: dispositivo) else return let session = AVCaptureSession () session.sessionPreset = .hd4K3840x2160
Qui, stiamo usando un guardia lascia
dichiarazione per verificare se il dispositivo (AVCaptureDevice
) ha una fotocamera. Quando si tenta di ottenere la fotocamera del dispositivo, è necessario specificare anche il tipo di supporto
, che, in questo caso, è .video
.
Quindi, creiamo un AVCaptureDeviceInput
, che è un input che porta il media dal dispositivo alla sessione di acquisizione.
Infine, creiamo semplicemente un'istanza di AVCaptureSession
classe, quindi assegnarlo a una variabile chiamata sessione
. Abbiamo personalizzato il bitrate della sessione e la qualità in Ultra-High-Definition (UHD) che è 3840 per 2160 pixel. Puoi sperimentare con questa impostazione per vedere cosa funziona per te.
Il prossimo passo nel fare il nostro AVCaptureSession
l'installazione è di creare un livello di anteprima, in cui l'utente può vedere l'input dalla telecamera. Aggiungeremo questo al UIImageView
abbiamo creato in precedenza nel nostro Storyboard. La parte più importante, però, è in realtà la creazione del nostro output per il modello Core ML da elaborare in seguito in questo tutorial, che faremo anche in questo passaggio.
Aggiungi il seguente codice direttamente sotto il codice del passaggio precedente:
et previewLayer = AVCaptureVideoPreviewLayer (session: session) previewLayer.frame = view.frame imageView.layer.addSublayer (previewLayer) lascia output = AVCaptureVideoDataOutput () output.setSampleBufferDelegate (self, queue: DispatchQueue (label: "videoQueue")) session.addOutput (produzione)
Per prima cosa creiamo un'istanza di AVCaptureVideoPreviewLayer
classe, quindi inizializzarlo con la sessione creata nel passaggio precedente. Fatto ciò, lo assegnamo a una variabile chiamata previewLayer
. Questo livello viene utilizzato per visualizzare effettivamente l'input dalla videocamera.
Successivamente, faremo in modo che il livello di anteprima riempia l'intero schermo impostando le dimensioni del riquadro su quelle della vista. In questo modo, l'aspetto desiderato persisterà per tutte le dimensioni dello schermo. Per mostrare effettivamente il livello di anteprima, lo aggiungeremo come sottolivello del UIImageView
che abbiamo creato quando stavamo creando l'interfaccia utente.
Ora, per la parte importante: creiamo un'istanza del AVCaptureDataOutput
classe e assegnarlo a una variabile chiamata produzione
.
Finalmente, abbiamo finito con la nostra sessione di cattura. Tutto ciò che resta da fare prima che il vero codice Core ML sia aggiungere l'input e avviare la sessione di acquisizione.
Aggiungi le seguenti due righe di codice direttamente sotto il passaggio precedente:
// Imposta l'ingresso di AVCaptureSession sull'input della telecamera del dispositivo session.addInput (input) // Avvia la sessione di acquisizione session.startRunning ()
Questo aggiunge l'input che abbiamo creato in precedenza al AVCaptureSession
, perché prima avevamo creato l'input e non l'avevamo aggiunto. Infine, questa riga di codice inizia la sessione che abbiamo passato così tanto tempo a creare.
Abbiamo già scaricato il modello, quindi il prossimo passo è di usarlo nella nostra app. Quindi iniziamo a usarlo per classificare le immagini.
Per iniziare, devi aggiungere il seguente metodo di delega alla tua app:
func captureOutput (_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, dalla connessione: AVCaptureConnection) // Il tuo codice va qui
Questo metodo delegato viene attivato quando viene scritto un nuovo frame video. Nella nostra app, ciò accade ogni volta che un frame viene registrato tramite il nostro feed video live (la velocità dipende esclusivamente dall'hardware su cui è in esecuzione l'app).
Ora, trasformeremo l'immagine (un fotogramma dal feed live) in un buffer di pixel, che è riconoscibile dal modello. Con questo, saremo in grado di creare in seguito un VNCoreMLRequest
.
Aggiungi le seguenti due righe di codice all'interno del metodo delegato creato in precedenza:
guardia lascia pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer (sampleBuffer) else return guardia lascia model = try? VNCoreMLModel (per: MobileNet (). Model) else return
Per prima cosa creiamo un buffer di pixel (un formato che Core ML accetta) dall'argomento passato attraverso il metodo delegate e quindi assegnarlo a una variabile chiamata pixelBuffer
. Quindi assegniamo il nostro MobileNet modello a una costante chiamata modello
.
Si noti che entrambi vengono creati utilizzando guardia lascia
dichiarazioni e che la funzione restituirà se uno di questi è zero
valori.
Dopo che le precedenti due righe di codice sono state eseguite, sappiamo per certo che abbiamo un buffer di pixel e un modello. Il prossimo passo sarebbe creare un VNCoreMLRequest
usando entrambi.
Subito sotto il passaggio precedente, incolla le seguenti righe di codice all'interno del metodo delegate:
let request = VNCoreMLRequest (model: model) (data, error) in // Il tuo codice va qui
Qui, stiamo creando una costante chiamata richiesta
e assegnandogli il valore di ritorno del metodo VNCoreMLRequest
quando il nostro modello è passato in esso.
Abbiamo quasi finito! Tutto ciò che dobbiamo fare ora è ottenere i nostri risultati (ciò che il modello pensa che la nostra immagine sia) e quindi mostrarli all'utente.
Aggiungi le prossime due righe di codice nel gestore di completamento della tua richiesta:
// Controlla se i dati sono nel formato corretto e li assegna ai risultati guard lasciate risultati = data.results as? [VNClassificationObservation] else return // Assegna il primo risultato (se esiste) a firstObject guard let firstObject = results.first else return
Se i risultati dei dati (dal gestore di completamento della richiesta) sono disponibili come una matrice di VNClassificationObservations
, questa linea di codice ottiene il primo oggetto dall'array che abbiamo creato in precedenza. Sarà quindi assegnato a una costante chiamata firstObject
. Il primo oggetto in questo array è quello per il quale il motore di riconoscimento delle immagini ha più confidenza.
Ricorda quando abbiamo creato le due etichette (sicurezza e oggetto)? Ora li useremo per mostrare ciò che il modello pensa che l'immagine sia.
Aggiungi le seguenti righe di codice dopo il passaggio precedente:
if firstObject.confidence * 100> = 50 self.objectLabel.text = firstObject.identifier.capitalized self.confidenceLabel.text = String (firstObject.confidence * 100) + "%"
Il Se
la dichiarazione assicura che l'algoritmo sia sicuro almeno al 50% circa la sua identificazione dell'oggetto. Quindi abbiamo appena impostato il firstObject
come il testo del objectLabel
perché sappiamo che il livello di fiducia è abbastanza alto. Mostreremo solo la percentuale di certezza usando la proprietà text di confidenceLabel
. Da firstObject.confidence
è rappresentato come un decimale, dovremo moltiplicare per 100 per ottenere la percentuale.
L'ultima cosa da fare è elaborare l'immagine attraverso l'algoritmo appena creato. Per fare ciò, dovrai digitare la seguente riga di codice direttamente prima di uscire captureOutput (_: didOutput: da :)
metodo delegato:
provare? VNImageRequestHandler (cvPixelBuffer: pixelBuffer, opzioni: [:]). Perform ([request])
I concetti che hai imparato in questo tutorial possono essere applicati a molti tipi di app. Spero ti sia piaciuto imparare a classificare le immagini usando il tuo telefono. Anche se potrebbe non essere ancora perfetto, puoi allenare i tuoi modelli in futuro per essere più precisi.
Ecco come dovrebbe apparire l'app quando viene eseguita:
Mentre sei qui, dai uno sguardo ai nostri altri post su machine learning e sviluppo di app per iOS!