Cu progresele tehnologice, suntem în punctul în care dispozitivele noastre pot utiliza camerele încorporate pentru a identifica cu precizie și a eticheta imagini utilizând un set de date pre-instruit. De asemenea, puteți să vă pregătiți propriile modele, dar în acest tutorial vom folosi un model open-source pentru a crea o aplicație de clasificare a imaginilor.
Vă voi arăta cum să creați o aplicație care să identifice imaginile. Vom începe cu un proiect Xcode gol și vom implementa o recunoaștere a imaginilor bazată pe învățarea automată la fiecare pas.
Înainte de a începe, asigurați-vă că aveți cea mai recentă versiune de Xcode instalată pe Mac. Acest lucru este foarte important deoarece Core ML va fi disponibil numai pe Xcode 9 sau mai nou. Puteți verifica versiunea dvs. deschizând Xcode și mergând la Xcode > Despre Xcode în bara de instrumente superioară.
Dacă versiunea dvs. de Xcode este mai veche decât Xcode 9, puteți să accesați Mac App Store și să o actualizați sau dacă nu o aveți, descărcați-o gratuit.
După ce vă asigurați că aveți versiunea corectă a Xcode, va trebui să creați un nou proiect Xcode.
Du-te și deschideți Xcode și faceți clic pe Creați un nou proiect Xcode.
Apoi, va trebui să alegeți un șablon pentru noul dvs. proiect Xcode. Este destul de obișnuit să folosiți a Vizualizare aplicație unică, deci mergeți mai departe și selectați că și faceți clic pe Următor →.
Puteți numi proiectul dvs. tot ce vă place, dar voi fi numit pe mine Clasificare imagine CoreML. Pentru acest proiect, vom folosi Swift, deci asigurați-vă că este selectat în Limba scapă jos.
Deoarece simulatorul Xcode nu are o cameră foto, va trebui să conectați iPhone-ul. Din păcate, dacă nu aveți un iPhone, va trebui să împrumutați unul pentru a putea urma împreună cu acest tutorial (și pentru orice alte aplicații legate de cameră). Dacă aveți deja un iPhone conectat la Xcode, puteți trece la următorul pas.
O caracteristică nouă în Xcode 9 este că puteți depana aplicația wireless pe un dispozitiv, deci să ne ocupăm de acest lucru:
În bara de meniu de sus, alegeți Fereastră > Dispozitive și simulatoare.În fereastra care apare, asigurați-vă că Dispozitive este selectat în partea de sus.
Acum conectați dispozitivul utilizând un cablu de trăsnet. Acest lucru ar trebui să facă aparatul să apară în panoul din stânga al ferestrei Dispozitive și simulatoare fereastră. Pur și simplu faceți clic pe dispozitivul dvs. și verificați Conectați-vă prin rețea cutie.
Acum veți putea să debugați fără fir pe acest iPhone pentru toate aplicațiile viitoare. Pentru a adăuga alte dispozitive, puteți urma un proces similar.
Când doriți să utilizați în cele din urmă iPhone-ul pentru depanare, pur și simplu selectați-l din meniul derulant de lângă Alerga buton. Ar trebui să vedeți o pictogramă de rețea de lângă ea, arătând că este conectată pentru depanare wireless. Am ales Vardhan's iPhone, dar trebuie să selectați dispozitivul dvs. specific.
Acum că ți-ai creat proiectul și ți-ai configurat iPhone-ul ca simulator, ne vom arunca cu puțin mai mult și vom începe programarea aplicației de clasificare a imaginilor în timp real.
Pentru a putea începe să vă creați aplicația de clasificare a imaginilor Core ML, va trebui mai întâi să obțineți modelul Core ML de pe site-ul Apple. După cum am menționat mai sus, puteți, de asemenea, să vă pregătiți propriile modele, dar acest lucru necesită un proces separat. Dacă parcurgeți partea de jos a site-ului Web de învățare al mașinilor Apple, veți putea alege și descărca un model.
În acest tutorial, voi folosi MobileNet.mlmodel model, dar puteți folosi orice model atâta timp cât îi cunoașteți numele și vă puteți asigura că se termină .mlmodel.
Există câteva cadre pe care va trebui să le importați împreună cu cele obișnuite UIKit
. În partea de sus a fișierului, asigurați-vă că sunt prezente următoarele declarații de import:
Import import UIKit AVKit import Vision
Vom avea nevoie AVKit
pentru că vom crea un AVCaptureSession
pentru a afișa un flux în timp ce clasificați imaginile în timp real. De asemenea, deoarece aceasta folosește viziunea pe computer, va trebui să importăm Viziune
cadru.
O parte importantă a acestei aplicații este afișarea etichetelor pentru datele de clasificare a imaginilor, precum și a fluxului video live de pe camera foto a dispozitivului. Pentru a începe proiectarea interfeței dvs. de utilizator, mergeți la dvs. Main.storyboard fişier.
Deplasați-vă la Biblioteca de obiecte și căutați un Vizualizare imagine. Pur și simplu trageți acest lucru pe controlerul dvs. de vizualizare pentru a-l adăugați. Dacă doriți, puteți adăuga și o imagine de tip placeholder pentru a obține o idee generală despre ce va arăta aplicația atunci când este utilizată.
Dacă alegeți să aveți o imagine cu substituent, asigurați-vă că Modul de conținut este setat sa Aspect Fit, și că bifați caseta care spune Clip to Bounds. În acest fel, imaginea nu va apărea întinsă și nu va apărea în afara ecranului UIImageView
cutie.
Iată ce ar trebui să arate acum panoul dvs. de prezentare:
Înapoi în Biblioteca de obiecte, căutați pentru Vedere și trageți-l pe controlerul de vizualizare. Acest lucru va servi ca un fundal frumos pentru etichetele noastre, astfel încât să nu se ascundă în imaginea afișată. Vom face această vizualizare translucidă, astfel încât o parte din stratul de previzualizare să fie încă vizibilă (aceasta este doar o atingere plăcută pentru interfața cu utilizatorul a aplicației).
Trageți-o în partea de jos a ecranului astfel încât să atingă recipientul pe trei laturi. Nu contează ce înălțime alegeți, deoarece vom stabili constrângeri în acest moment într-un moment.
Aceasta, probabil, este cea mai importantă parte a interfeței noastre cu utilizatorul. Trebuie să afișăm ceea ce aplicația noastră consideră că este obiectul și cât de sigur este (nivelul de încredere). După cum probabil ați ghicit, va trebui să trageți două Eticheta(E)de la Biblioteca de obiecte la punctul de vedere pe care tocmai l-am creat. Trageți aceste etichete undeva în apropierea centrului, așezate unul peste celălalt.
Pentru eticheta de sus, mergeți la Atribuții Inspector și faceți clic pe T butonul de lângă stilul și dimensiunea fontului și, în fereastra pop-up, selectați Sistem dupa cum font. Pentru a diferenția acest lucru de eticheta de încredere, selectați Negru dupa cum stil. În cele din urmă, schimbați mărimea la 24.
Pentru eticheta de jos, urmați aceiași pași, dar în loc să selectați Negru dupa cum stil, Selectați Regulat, și pentru mărimea, Selectați 17.
Imaginea de mai jos arată cum vă Storyboard ar trebui să arate când ați adăugat toate aceste vederi și etichete. Nu vă faceți griji dacă nu sunt exact aceleași cu a ta; le vom adăuga constrângeri în următorul pas.
Pentru ca această aplicație să funcționeze pe diferite dimensiuni ale ecranului, este important să adăugați constrângeri. Acest pas nu este esențial pentru restul aplicației, dar este foarte recomandat să faceți acest lucru în toate aplicațiile dvs. pentru iOS.
Primul lucru de constrângere este al nostru UIImageView
. Pentru aceasta, selectați vizualizarea imaginii și deschideți Pin Meniu în bara de instrumente de jos (aceasta arată ca un pătrat cu constrângerile și este al doilea din dreapta). Apoi, va trebui să adăugați următoarele valori:
Înainte de a continua, asigurați-vă că Constrângeți-vă la margini caseta nu este bifată, deoarece acest lucru va crea o discrepanță între ecran și afișarea reală a imaginii. Apoi, lovit introduce.Acum tu UIImageView
este centrat pe ecran și ar trebui să arate exact pe toate dimensiunile dispozitivului.
Acum, următorul pas este de a restrânge vederea pe care apar etichetele. Selectați vizualizarea, apoi mergeți la Pin Meniu din nou. Adăugați următoarele valori:
Acum, pur și simplu lovit introduce pentru a salva valorile. Afișarea dvs. este acum limitată în partea de jos a ecranului.
Deoarece vizualizarea este acum limitată, puteți adăuga constrângeri la etichete în raport cu vizualizarea în locul ecranului. Acest lucru este util dacă mai târziu decideți să schimbați poziția etichetelor sau a vederii.
Selectați ambele etichete și puneți-le într-o vizualizare de stivă. Dacă nu știți cum să faceți acest lucru, pur și simplu trebuie să apăsați butonul (al doilea din stânga) care arată ca o teanc de cărți cu săgeată în jos. Veți vedea apoi că butoanele devin un obiect selectabil.
Faceți clic pe vizualizarea stack-ului dvs., apoi faceți clic pe Aliniați meniul (a treia din stânga) și asigurați-vă că sunt bifate următoarele casete:
Acum, lovit introduce. Etichetele dvs. trebuie să fie centrate în vizualizarea din pasul anterior și vor apărea acum la fel în toate dimensiunile ecranului.
Ultimul pas în interfața cu utilizatorul ar fi să conectați elementele la dvs. ViewController ()
clasă. Pur și simplu deschideți Editor asistent și apoi Control-clic și Trage fiecare element din partea de sus a clasei tale din interior ViewController.swift. Iată ce le voi numi în acest tutorial:
UILabel
: objectLabel
UILabel
: confidenceLabel
UIImageView
: ImageView
Bineînțeles, le puteți numi oricând doriți, dar acestea sunt numele pe care îl veți găsi în codul meu.
Feed-ul video live va necesita o AVCaptureSession
, așa că să creăm una acum. Vom afișa, de asemenea, intrarea camerei în timp util utilizatorului. Efectuarea unei sesiuni de captare este un proces destul de lung și este important să înțelegeți cum să faceți acest lucru deoarece va fi util în orice altă dezvoltare pe care o faceți utilizând camera de pe bordul oricărui dispozitiv Apple.
Pentru a începe, putem crea o extensie de clasă și apoi să o facem conformă AVCaptureVideoDataOutputSampleBufferDelegate
protocol. Puteți face cu ușurință acest lucru în cadrul realității ViewController
dar folosim cele mai bune practici aici pentru ca codul să fie curat și organizat (așa se va face pentru aplicațiile de producție).
Ca să putem numi asta înăuntru viewDidLoad ()
, va trebui să creați o funcție numită setupSession ()
care nu iau nici un fel de parametri. Puteți să vă numiți tot ceea ce doriți, dar să aveți grijă de denumire atunci când numim această metodă mai târziu.
După ce ați terminat, codul dvs. ar trebui să arate după cum urmează:
// MARK: - Extensie AVCaptureSession ViewController: AVCaptureVideoDataOutputSampleBufferDelegate func setupSession () // Codul dvs. merge aici
Primul pas în crearea sesiunii de captare este de a verifica dacă aparatul are sau nu o cameră foto. Cu alte cuvinte, nu încercați să folosiți aparatul foto dacă nu există cameră. Apoi, va trebui să creați sesiunea de captură reală.
Adăugați următorul cod la adresa dvs. setupSession ()
metodă:
pază a lăsa dispozitiv = AVCaptureDevice.default (pentru: .video) altceva return garda lăsați intrarea = încercați? AVCaptureDeviceInput (dispozitiv: dispozitiv) altceva return let session = AVCaptureSession () session.sessionPreset = .hd4K3840x2160
Aici, folosim a paza a lăsat
pentru a verifica dacă dispozitivul (AVCaptureDevice
) are o cameră foto. Când încercați să obțineți camera aparatului, trebuie să specificați și MediaType
, care, în acest caz, este .video
.
Apoi, creăm un AVCaptureDeviceInput
, care este o intrare care aduce mediul de pe dispozitiv la sesiunea de captare.
În cele din urmă, vom crea doar o instanță a AVCaptureSession
și apoi alocați-o unei variabile numite sesiune
. Am personalizat bitrate-ul și calitatea sesiunii la Ultra-High Definition (UHD), care este de 3840 la 2160 de pixeli. Puteți experimenta această setare pentru a vedea ce funcționează pentru dvs..
Următorul pas în a ne face AVCaptureSession
setup este crearea unui strat de previzualizare, unde utilizatorul poate vedea intrarea de la aparatul foto. Vom adăuga acest lucru pe UIImageView
am creat mai devreme în Storyboard. Cea mai importantă parte, totuși, este crearea de fapt a producției noastre pentru modelul ML Core pentru a procesa mai târziu în acest tutorial, pe care o vom face și în acest pas.
Adăugați următorul cod direct sub codul din pasul anterior:
și previewLayer = AVCaptureVideoPreviewLayer (sesiune: sesiune) previewLayer.frame = view.frame imageView.layer.addSublayer (previewLayer) permite ieșire = AVCaptureVideoDataOutput () output.setSampleBufferDelegate (etichetă: "videoQueue") session.addOutput (output)
Mai întâi creați o instanță a AVCaptureVideoPreviewLayer
și apoi inițializați-o cu sesiunea pe care am creat-o în pasul anterior. După ce sa terminat, îl atribuim unei variabile numite previewLayer
. Acest strat este utilizat pentru a afișa efectiv intrarea din cameră.
Apoi vom face ca stratul de previzualizare să umple întregul ecran prin setarea dimensiunilor cadrului la cele din vizualizare. În acest fel, aspectul dorit va persista pentru toate dimensiunile ecranului. Pentru a afișa efectiv stratul de previzualizare, îl vom adăuga sub forma unui substrat al UIImageView
pe care am creat-o când făceam interfața cu utilizatorul.
Acum, pentru partea importantă: Creăm o instanță a AVCaptureDataOutput
clasă și să o atribuiți unei variabile numite producție
.
În cele din urmă, am terminat cu sesiunea noastră de captură. Tot ce trebuie să faceți înainte de actualul cod ML Core este să adăugați intrarea și să începeți sesiunea de captare.
Adăugați următoarele două linii de cod direct sub pasul anterior:
// Setează intrarea AVCaptureSession în sesiunea de intrare a aparatului foto.addInput (intrare) // Începe sesiunea de captare session.startRunning ()
Aceasta adaugă intrarea pe care am creat-o anterior AVCaptureSession
, deoarece înainte de aceasta am creat doar intrarea și nu l-am adăugat. În sfârșit, această linie de cod începe sesiunea pe care am petrecut-o atât de mult timp creând.
Am descarcat deja modelul, deci urmatorul pas este sa il folosim in aplicatia noastra. Deci, haideți să începeți cu utilizarea acesteia pentru a clasifica imaginile.
Pentru a începe, va trebui să adăugați următoarea metodă de delegat în aplicația dvs.:
func captureOutput (_ ieșire: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, de la conexiune: AVCaptureConnection) // Codul dvs. merge aici
Această metodă delegată este declanșată atunci când este scris un nou cadru video. În aplicația noastră, acest lucru se întâmplă de fiecare dată când un cadru este înregistrat prin fluxul video live (viteza acestuia depinde numai de hardware-ul pe care rulează aplicația).
Acum, vom transforma imaginea (un cadru din fluxul live) într-un tampon de pixeli, care poate fi recunoscut de model. Cu aceasta, vom putea crea ulterior o VNCoreMLRequest
.
Adăugați următoarele două linii de cod în cadrul metodei delegate pe care ați creat-o mai devreme:
paza permite pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer (sampleBuffer) altceva return paza permite model = incercati? VNCoreMLModel (pentru: modelul MobileNet ()) altceva return
Mai întâi vom crea un tampon pixel (un format acceptat de Core ML) din argumentul transmis prin metoda delegat, și apoi îl vom atribui unei variabile numite pixelBuffer
. Apoi ne alocăm MobileNet model la o constantă numită model
.
Observați că ambele sunt create folosind paza a lăsat
și că funcția va reveni dacă oricare dintre acestea este zero
valorile.
După ce au fost executate cele două linii anterioare de cod, știm sigur că avem un tampon pixel și un model. Următorul pas ar fi crearea unui VNCoreMLRequest
folosind ambele.
Sub pasul anterior, lipiți următoarele linii de cod în interiorul metodei delegate:
lasă cererea = VNCoreMLRequest (model: model) (date, eroare) în // codul dvs. merge aici
Aici, creăm o constantă numită cerere
și atribuirea acesteia valoarea de retur a metodei VNCoreMLRequest
când modelul nostru este trecut în ea.
Aproape am terminat! Tot ce trebuie să facem acum este să obținem rezultatele noastre (ceea ce modelul gândește imaginea noastră) și apoi să le afișeze utilizatorilor.
Adăugați următoarele două linii de cod în procedura de completare a solicitării dvs.:
// Verifică dacă datele sunt în formatul corect și le atribuie pazei rezultatelor let rezultatele = rezultatele de date ca? [VNClassificationObservation] else return // atribuie primului rezultat (dacă există) la paza firstObject let firstObject = results.first else return
Dacă rezultatele din date (de la managerul de completare al cererii) sunt disponibile ca o serie de VNClassificationObservations
, această linie de cod primește primul obiect din matricea pe care am creat-o mai devreme. Acesta va fi apoi atribuit unei constante numite firstObject
. Primul obiect din această matrice este cel pentru care motorul de recunoaștere a imaginii are cea mai mare încredere.
Amintiți-vă când am creat cele două etichete (încredere și obiect)? Acum le vom folosi pentru a afișa ceea ce modelul crede că este imaginea.
Adăugați următoarele rânduri de cod după pasul anterior:
dacă primaObject.confidence * 100> = 50 self.objectLabel.text = firstObject.identifier.capitalized self.confidenceLabel.text = String (firstObject.confidence * 100) + "%"
dacă
declarația asigură că algoritmul are cel puțin 50% siguranță cu privire la identificarea obiectului. Apoi am setat firstObject
ca textul objectLabel
deoarece știm că nivelul de încredere este suficient de ridicat. Vom afișa doar procentul de certitudine folosind proprietatea textului din confidenceLabel
. De cand firstObject.confidence
este reprezentat ca zecimal, va trebui să înmulțim cu 100 pentru a obține procentajul.
Ultimul lucru pe care trebuie să-l faceți este să procesați imaginea prin algoritmul pe care tocmai l-am creat. Pentru a face acest lucru, va trebui să introduceți direct următoarea linie de cod înainte de a ieși din captureOutput (_: didOutput: de la :)
metoda delegat:
încerca? VNImageRequestHandler (cvPixelBuffer: pixelBuffer, opțiuni: [:]) efectuați ([request])
Conceptele pe care le-ați învățat în acest tutorial pot fi aplicate pentru multe tipuri de aplicații. Sper că v-ați bucurat să învățați să clasificați imagini utilizând telefonul. În timp ce este posibil să nu fie încă perfectă, puteți să vă pregătiți propriile modele în viitor pentru a fi mai exacte.
Iată ce ar trebui să arate aplicația atunci când se face:
În timp ce sunteți aici, consultați câteva dintre celelalte postări despre dezvoltarea de aplicații pentru iOS și mașină!