This shows you the differences between two versions of the page.
irva:laboratoare:04 [2022/10/24 18:12] maria_anca.balutoiu [Activare API ARCore Cloud Anchor] |
irva:laboratoare:04 [2023/10/23 12:49] (current) maria_anca.balutoiu [Tasks] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Laboratorul 04. Cloud Anchors ===== | + | ===== Laboratorul 04. Augmented Images ===== |
- | O ancoră cloud este un tip special de ancoră care permite salvarea și reluarea experiențelor AR. Folosind Cloud Anchors API, putem crea spații interactive pe care să le ancorăm în locații din lumea reală și pe care să le distribuim și altor persoane. Practic, spre deosebire de o ancoră clasică, orice obiect cu o ancoră cloud atașată va fi vizibil simultan și oricând altcândva de oricâte device-uri. Ancorele cloud sunt disponibile atât pentru device-uri Android, cât și pentru iOS. | + | |
- | ===== Cum funcționează Ancorele Cloud ===== | + | API-ul Augmented Images din ARCore ne permite să creăm aplicații care pot detecta și augmenta imagini 2D din mediul înconjurător al utilizatorului (cum ar fi postere, tablouri, ambalaje). API-ul se bazează pe setarea unui set de imagini de referință. ARCore utilizează pe urmă un algoritm computer vision pentru a extrage caracteristici din informația grayscale a fiecărei imagini și salvează o reprezentare a acestor caracteristici într-o bază de date de imagini augmentate. La runtime, ARCore caută aceste caracteristici pe suprafețele plane din mediul înconjurător al utilizatorului. Asta permite ARCore să detecteze aceste imagini în lumea reală și să estimeze poziția, orientarea și dimensiunea lor. |
- | ARCore se conectează la serviciul ARCore Cloud Anchor pentru hosting și resolving. Deci, avem nevoie de conexiune la internet pentru a putea folosi ancore Cloud. | + | |
- | Modul de funcționare al ancorelor cloud: | + | {{ :irva:laboratoare:augmented-images-demo.gif?600 |}} |
- | - Utilizatorul crează o ancoră locală mediului înconjurător | + | |
- | - **Hosting.** ARCore încarcă informațiile despre ancora locală în serviciul ARCore Cloud Anchor. Serviciul întoarce un id unic pentru acea ancoră. | + | |
- | - Aplicația distribuie acel id unic către toți ceilalți utilizatori. | + | |
- | - **Resolving.** Utilizatorii care au primit acel id unic pot recrea aceiași ancoră folosind serviciul ARCore Cloud Anchor. | + | |
- | ===== Hosting ===== | + | ===== Capabilități Tehnice ===== |
- | Pentru a crea și a hosta o ancoră, ARCore folosește o hartă de feature-uri 3D a spațiului înconjurător. Pentru a obține această hartă, camera telefonului trebuie să mapeze mediul înconjurător din jurul punctului de interes din cât mai multe unghiuri și poziții diferite înainte de hosting-ul propriu-zis. Serviciul ARCore Cloud Anchor crează pe urmă o hartă de caracteristici 3D ale spațiului și întoarce id-ul unic. | + | * ARCore poate urmări simultan până la 20 de imagini. Cu toate acestea, ARCore nu va detecta sau urmări instanțe multiple ale aceleași imagini. |
+ | * Fiecare bază de date de imagini augmentate poate reține maxim 1000 de imagini de referință. Nu există nicio limită pentru numărul de baze de date folosite de o aplicație, dar la un anumit moment de timp o singură bază de date poate fi activă. O bază de date poate fi îmbogățită cu imagini la runtime cu condiția ca baza de date să nu depășească 1000 de imagini. | ||
+ | * Când adăugăm o imagine într-o bază de date putem specifica dimensiunea imaginii. Acest lucru va rezulta în îmbunătățirea performanței de detecție. Dacă nu este setată dimensiunea imaginii, ARCore va estima dimensiunea periodic. | ||
+ | * ARCore poate detecta imagini care fie se află într-o poziție fixă (de exemplu un tablou pe un perete), fie se mișcă (de exemplu o reclamă pe un autobuz). | ||
+ | * Odată ce o imagine este detectată, ARCore va urmări poziția și orientarea imaginii chiar și când imaginea nu se mai află în raza camerei telefonului. În cazul acesta, ARCore presupune că imaginea este statică, deci aceasta nu se mișcă, ci doar telefonul utilizatorului. | ||
+ | * Toată procesarea are loc pe dispozitiv. Nu este necesară o conexiune la internet pentru a detecta și a urmări imagini. Baza de date de imagini este, la rândul său, locală. | ||
- | {{ :irva:laboratoare:cloud-anchor-part-1.gif?600 |}} | + | ===== Cerințe de Funcționare ===== |
+ | Pentru a fi detectate, imaginile trebuie: | ||
+ | * Să fie plate (un ambalaj de pe o sticlă nu este garantat că va fi detectat) | ||
+ | * Să fie clar vizibile de camera telefonlui. Imaginile nu vor fi detectate dacă sunt parțial ascunse sau dacă telefonul este mișcat prea rapid. | ||
+ | * Să reprezinte cel puțin 25% din imaginea procesată de camera telefonului pentru a fi detectate inițial. | ||
- | <code c#> | ||
- | public void HostAnchor() | ||
- | { | ||
- | /* Try and host cloud anchor */ | ||
- | if (arAnchorManager.HostCloudAnchor(anchor, 1) == null) | ||
- | { | ||
- | /* If no unique ID is returned, the hosting process has failed */ | ||
- | } | ||
- | else | ||
- | { | ||
- | anchorHostInProgress = true; | ||
- | } | ||
- | } | ||
- | private void CheckHostingProgress() | + | ===== Selectarea Imaginilor de referință ===== |
- | { | + | Similar Vuforia, nici ARCore nu poate detecta orice imagine. Astfel, imaginile folosite trebuie să îndeplinească o serie de criterii: |
- | /* Get the cloud anchor state */ | + | * Rezoluția unei poze ar trebui să fie de **cel puțin 300 x 300 pixeli**. Imagini cu rezoluții foarte mari nu îmbunătățesc performanța detecției. |
- | CloudAnchorState cloudAnchorState = cloudAnchor.cloudAnchorState; | + | * Imaginile trebuie să fie în format **PNG** sau **JPEG**. |
+ | * Informația de culoare nu este folosită, ci imaginea grayscale. | ||
+ | * **Evitați imaginile cu rată de compresie mare** (interferează cu extracția de caracteristici). | ||
+ | * **Evitați imaginile care conțin un număr foarte mare de caracteristici geometrice sau care conțin prea puține caracteristici**. Astfel de imagini vor fi greu detectate. | ||
+ | * **Evitați imaginile cu modele repetitive** | ||
- | /* If the process was a success */ | + | {{ :irva:laboratoare:augmentedimages.png?750 |}} |
- | if (cloudAnchorState == CloudAnchorState.Success) | + | |
- | { | + | |
- | anchorHostInProgress = false; | + | |
- | + | ||
- | /* Save the unique ID */ | + | |
- | anchorIdToResolve = cloudAnchor.cloudAnchorId; | + | |
- | } | + | |
- | else | + | |
- | { | + | |
- | /* If the process is completed, but not successfully */ | + | |
- | if (cloudAnchorState != CloudAnchorState.TaskInProgress) | + | |
- | { | + | |
- | /* There was an error while hosting the cloud anchor */ | + | |
- | anchorHostInProgress = false; | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | void Update() | + | ===== Crearea Bazei de Date de Imagini ===== |
- | { | + | * Baza de date salvează o reprezentare comprimată a caracteristicilor extrase din imaginea grayscale a imaginii de referință. Fiecare imagine ocupă aproximativ 6kB. |
- | if(anchorHostInProgress) | + | * Adăugarea unei imagini la runtime într-o bază de date durează aproximativ 30ms. |
- | { | + | * Este indicat să se adauge imagini pe thread-uri separate pentru a evita blocarea thread-ului interfeței grafice. |
- | CheckHostingProgress(); | + | * Dacă cunoașteți dimensiunea imaginii de input specificați-o. Informația aceasta îmbunătățește performanța detecției imaginii în special pentru imagini fizice foarte mari (mai mari de 75cm). |
- | } | + | * Evitați să aveți în baza de date foarte multe imagini nefolosite. |
- | } | + | |
- | </code> | + | |
- | ===== Resolving ===== | + | |
- | Când un alt utilizator aflat în același mediu îndreaptă camera telefonului către zona unde a fost salvată ancora cloud, serviciul ARCore Cloud Anchor compară periodic caracteristicile vizuale din scenă cu harta de caracteristici 3D care a fost creată anterior. ARCore folosește aceste comparații pentru a determina poziția și orientarea utilizatorului relative la ancora cloud. | + | |
- | <code c#> | + | ===== Crearea Bazei de Date de Imagini ===== |
- | cloudAnchor = arAnchorManager.ResolveCloudAnchorId(anchorIdToResolve); | + | - Click dreapta în **Project -> Create -> XR -> Reference Image Library** |
- | </code> | + | - Click pe obiectul creat -> **Add Image** din Inspector |
+ | - Populați baza de date cu imagini | ||
+ | - Atașați scriptul **AR Tracked Image Manager** pe un GameObject din scenă | ||
+ | - **Serialized Library** va fi baza de date creată anterior | ||
+ | - **Tracked Image prefab** va fi obiectul care se va instanția când o imagine din baza de date este detectată | ||
- | {{ :irva:laboratoare:cloud-anchor-part-2.gif?600 |}} | + | {{ :irva:laboratoare:baza_de_date.png?600 |}} |
- | ===== Folosirea Ancorelor Cloud ===== | + | {{ :irva:laboratoare:tracked_image.png?600 |}} |
- | Pentru a putea folosi ancore cloud este nevoie de o formă de autentificare. În cazul Android, ARCore Extensions oferă suport pentru Keyless și API Key pentru autentificare. Pentru iOS, ARCore Extensions oferă suport pentru Authentication token și API Key. Autentificarea trebuie activată manual în **Project Settings -> XR -> ARCore Extensions**. | + | |
- | <note warning>API-ul ARCore Cloud Anchor necesită instalarea **ARCore Extensions for AR Foundation**.</note> | + | ===== Crearea Bazei de Date de Imagini la Runtime ===== |
+ | Putem observa că în pașii prezentați anterior baza de date de imagini este creată înainte de compilare. Deci trebuie să cunoaștem toate imaginile pe care le dorim în proiect înainte de a crea .apk-ul. Acest aspect nu este însă practic. De multe ori poate vom dori să folosim imagini aleatoare. Drept urmare, o bază de date configurată anterior nu este fezabilă. Deci, vom avea nevoie să creăm o bază de date proprie la runtime: | ||
+ | - Ștergem vechea bază de date de imagini (în caz că există); deci ștergem componenta **ARTrackedImageManager** dacă există | ||
+ | - Adăugăm o nouă componentă **ARTrackedImageManager** obiectului | ||
+ | - Creăm baza de date la runtime | ||
+ | - Adăugăm imagini în baza de date | ||
+ | - Setăm baza de date nou creată și numărul maxim de imagini mișcătoare. | ||
+ | - Activăm noua baza de date | ||
+ | - Setăm funcția de gestiune a schimbării stării de tracking a imaginilor | ||
- | ===== Activare API ARCore Cloud Anchor ===== | + | <code c#> |
- | Înainte de a putea utiliza ancore cloud în aplicațiile noastre, trebuie mai întâi să activăm API-ul ARCore Cloud Anchor într-un proiect nou sau deja existent de pe [[https://console.cloud.google.com/|Google Cloud Platform]]. Activarea API-ului se face [[https://console.cloud.google.com/apis/library/arcorecloudanchor.googleapis.com|aici]]. | + | /* Destroy the previous ARTrackedImageManager component */ |
+ | DestroyImmediate(gameObject.GetComponent<ARTrackedImageManager>()); | ||
- | Odată făcut acest pas, în funcție de metoda de autentificare folosită, trebuie să setăm una din următoarele (prin apăsarea butonului **Create Credentials**): | + | /* Add a new ARTrackedImageManager component */ |
- | * API keys (iOS și Android) | + | ARTrackedImageManager trackImageManager = gameObject.AddComponent<ARTrackedImageManager>(); |
- | * OAuth 2.0 Client IDs (Android) | + | |
- | * Service Accounts (iOS) | + | |
- | {{ :irva:laboratoare:autentificare_cloud.png?750 |}} | + | /* Create a new database */ |
+ | var library = trackImageManager.CreateRuntimeLibrary(); | ||
- | <note important>În cazul OAuth 2.0 Client IDs va trebui specificat SHA-1 certificate fingerprint al aplicației. Pentru a afla acest lucru, trebuie să facem următorii pași: | + | /* Add images to the database */ |
- | - În Unity deschidem **File -> Build Settings**. | + | if (library is MutableRuntimeReferenceImageLibrary mutableLibrary) |
- | - Deschidem **Player Settings -> Publishing Settings**. | + | { |
- | - **Create new keystore -> Browse keystore**. | + | mutableLibrary.ScheduleAddImageWithValidationJob(imageToAdd, "Image Name", 0.5f /* 50 cm */); |
- | - Salvăm fișierul care este creat (în folderul proiectului). | + | } |
- | - Setăm o parolă. | + | |
- | - La **Alias** setăm o nouă cheie. | + | |
- | - Completăm toate câmpurile care apar. | + | |
- | - Căutăm executabilul **keytool.exe**. | + | |
- | - Deschidem un terminal la locația executabilului și rulăm următoarea comandă (ni se va cere parola setată anterior): | + | |
- | <code> | + | /* Set max number of moving images */ |
- | keytool -exportcert -alias examplealias -keystore <calea către fișierul creat de Unity>\user.keystore -list -v | + | trackImageManager.requestedMaxNumberOfMovingImages = 3; |
- | </code> | + | |
- | În consolă vom avea SHA-1 certificate fingerprint. | + | /* Set the reference library */ |
+ | trackImageManager.referenceLibrary = library; | ||
- | <note warning> | + | /* Enable current ARTrackedImageManager */ |
- | Atenție! Odată setată parola, de fiecare dată când pornim Unity, va fi necesar să scriem parola în **Player Settings**. Atfel, build-ul nu se va putea face. | + | trackImageManager.enabled = true; |
- | </note> | + | |
- | </note> | + | |
+ | /* Attach the function for handling the tracking state of the images */ | ||
+ | trackImageManager.trackedImagesChanged += OnTrackedImagesChanged; | ||
+ | </code> | ||
- | ===== Activarea Ancorelor Cloud în Aplicație ===== | + | <code c#> |
- | ===== Keyless Authentication ===== | + | void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs) |
- | Opțiunea de autentificare keyless este disponibilă pentru dispozitivele **Android**. Aceasta permite salvarea unei ancore cloud pentru **maxim 365 de zile**. | + | { |
+ | foreach (ARTrackedImage trackedImage in eventArgs.added) | ||
+ | { | ||
+ | |||
+ | } | ||
- | Pași pentru setarea acestui mod de autentificare: | + | foreach (ARTrackedImage trackedImage in eventArgs.updated) |
- | * Setăm **Keyless** din meniul de setări **Cloud Anchors**. | + | { |
- | * Creăm un client OAuth pentru aplicația curentă Android în Google Developers Console. | + | |
+ | } | ||
- | {{ :irva:laboratoare:settingscloudanchors.png?700 |}} | + | foreach (ARTrackedImage trackedImage in eventArgs.removed) |
+ | { | ||
+ | |||
+ | } | ||
+ | } | ||
+ | </code> | ||
- | ===== Token authentication ===== | + | ===== Optimizarea Image Tracking ===== |
- | Opțiunea de autentificare pe bază de token este disponibilă pentru dispozitivele **iOS**. Aceasta permite salvarea unei ancore cloud pentru **maxim 365 de zile**. Pentru setare, urmați pașii de [[https://developers.google.com/ar/develop/unity-arf/cloud-anchors/developer-guide-ios#token-authentication|aici]]. | + | * Dacă imaginea nu își va schimba niciodată poziția (de exemplu, un tablou), puteți atașa o ancoră imaginii pentru a crește stabilitatea detectării imaginii. |
- | ===== API Key Authentication ===== | + | * Imaginea fizică trebuie să ocupe cel puțin 25% din imaginea produsă de cameră pentru a putea detecta inițial imaginea. |
- | Autentificarea pe bază de cheie API este disponibilă atât pe dispozitive **iOS**, cât pe dispozitive **Android**. Aceasta permite salvarea unei ancore pentru **o singură zi**. | + | * Nu utilizați poziția, orientarea și dimensiunea imaginii atâta timp cât **tracking state** NU este **Tracked**. Când o imagine este inițial detectată de ARCore și dimensiunea acesteia nu a fost specificată, starea sa va fi **Paused**. Asta înseamnă ca ARCore a recunoscut imaginea, dar nu are încă suficiente informații pentru a putea estima poziția și orientarea sa. |
- | Pași pentru configurare: | ||
- | - Creăm o cheie pentru API pe Google Cloud Platform. | ||
- | - Adăugăm noua cheie API proiectului: | ||
- | * În Unity: **Edit -> Project Settings -> XR -> ARCore Extensions**. | ||
- | * Adăugăm cheia în câmpul **Cloud Anchor API Keys**. | ||
- | ===== Calitatea Mapării Feature Points ===== | ||
- | **FeatureMapQuality** indică gradul de calitate al punctelor caracteristice detectate de ARCore de la o anumită poziție. Ancorele cloud care sunt salvate folosind puncte caracteristice de o calitate înaltă vor avea în general rezultate cât mai bune. Dacă gradul de calitate al hărții de puncte caracteristice nu poate fi estimat pentru o anumită poziție și orientare, atunci **EstimateFeatureMapQualityForHosting** loghează un mesaj de avertizare și are rezultatul **FeatureMapQuality.Insufficient**. Acest rezultat indică faptul că ARCore va avea cel mai probabil dificultăți în rezolvarea ancorei cloud. Deci, pentru rezultate optime, trebuie să ne asigurăm că **FeatureMapQuality** indică un rezultat suficient de bun. | ||
- | |||
- | <code c#> | ||
- | FeatureMapQuality quality = arAnchorManager.EstimateFeatureMapQualityForHosting(GetCameraPose()); | ||
- | </code> | ||
===== Tasks ===== | ===== Tasks ===== | ||
<note tip> | <note tip> | ||
- | + | Vom folosi scena **Augmented Images** din scheletul de laborator. Acesta poate fi descărcat de [[https://github.com/Maria-Anca-Balutoiu/IRVA_AR|aici]]. Scriptul necesar pentru rezolvarea laboratorului se află în **Assets->Scripts**: **RuntimeImageLibrary.cs**. | |
- | Vom folosi scena **Cloud Anchors** din scheletul de laborator. Acesta poate fi descărcat de [[https://github.com/Maria-Anca-Balutoiu/IRVA_AR.git|aici]]. Scripturile necesare pentru rezolvarea laboratorului se află în **Assets->Scripts**: **ARCloudAnchorManager.cs** și **CloudAnchorObjectPlacement.cs**. | + | |
- | + | ||
- | Inițial în scenă aveți 3 butoane: | + | |
- | * **Host.** Butonul este mapat la funcția **HostAnchor()** prin care veți crea și hosta o nouă ancoră cloud. | + | |
- | * **Resolve.** Butonul este mapat la funcția **Resolve()** prin care veți rezolva o ancoră cloud deja existentă. | + | |
- | * **Delete.** Butonul este mapat la funcția **RemovePlacement()** prin care veți șterge ancora existentă. | + | |
- | + | ||
- | Pentru testare, ancora cloud va fi mereu atașată pe un cub. Deci, când apăsați butonul **Resolve** pe ecran ar trebui să vă apară cubul la poziția la care l-ați pus inițial. | + | |
- | + | ||
- | Workflow-ul aplicației este următorul: | + | |
- | - Adăugăm un cub cu o ancoră pe ecran. | + | |
- | - Hostăm ancora în cloud. | + | |
- | - Ștergem cubul de pe ecran. | + | |
- | - Readucem cubul pe ecran la exact aceiași poziție prin rezolvarea ancorei. | + | |
</note> | </note> | ||
+ | - Creați o bază de date înainte de compilare cu minim 3 imagini. | ||
+ | - Augmentați imaginile din baza de date creată. | ||
+ | - Creați o bază de date la runtime cu minim o imagine și augmentați imaginea. | ||
+ | - **Bonus:** Adăugați un buton pe ecran cu care veți face switch între cele două baze de date. | ||
- | - Implementați una din cele 3 metode pentru activarea API-ului ARCore Cloud Anchor. | + | <note warning>Putem avea o singură bază de date de imagini activă la un moment dat. Deci, când adăugăm o nouă bază de date de imagini, trebuie să ștergem ultima bază de date existentă.</note> |
- | - Adăugați un cub pe ecran la poziția degetului. Atașați cubului o ancoră. | + | |
- | - Salvați ancora în cloud. | + | |
- | - Ștergeți cubul de pe ecran la apăsarea butonului **Delete**. | + | |
- | - Folosind ancora din cloud, afișați cubul în poziția în care l-ați plasat inițial. | + | |