Overzicht van runtime-SDK
Deze sectie biedt een algemeen overzicht van de Object Anchors Runtime SDK, die wordt gebruikt om objecten te detecteren met behulp van een Object Anchors-model. U krijgt inzicht in hoe een object wordt weergegeven en waarvoor de verschillende onderdelen worden gebruikt.
Alle typen die hieronder worden beschreven, zijn te vinden in een van de volgende naamruimten: Microsoft.Azure.ObjectAnchors, Microsoft.Azure.ObjectAnchors.Diagnostics en Microsoft.Azure.ObjectAnchors.SpatialGraph.
Typen
ObjectModel
Een ObjectModel vertegenwoordigt de geometrie van een fysiek object en codeert de benodigde parameters voor detectie en pose-schatting. Deze moet worden gemaakt met behulp van de Object Anchors-service. Vervolgens kan een toepassing het gegenereerde modelbestand laden met behulp van de Object Anchors-API en een query uitvoeren op de mesh die in dat model is ingesloten voor visualisatie.
ObjectSearchArea
Een ObjectSearchArea geeft de ruimte op die moet worden gezocht naar een of meer objecten. Het wordt gedefinieerd door een knooppunt-id voor ruimtelijke grafieken en ruimtelijke grenzen in het coördinatensysteem dat wordt vertegenwoordigd door de id van het knooppunt voor ruimtelijke grafieken. De Object Anchors Runtime SDK ondersteunt vier typen grenzen, namelijk het gebied van weergave, het begrenzingsvak, de bol en een locatie.
AccountInformation
Met AccountInformation worden de id, sleutel en domein voor uw Azure Object Anchors-account opgeslagen.
ObjectAnchorsSession
Een ObjectAnchorsSession vertegenwoordigt een Azure Object Anchors-sessie die wordt gebruikt om ObjectObserver-exemplaren te maken die worden gebruikt om objecten in de fysieke wereld te detecteren.
ObjectObserver
Een ObjectObserver laadt objectmodellen, detecteert de exemplaren en rapporteert 6-DoF-poses van elk exemplaar in het HoloLens-coördinaatsysteem.
Hoewel elk objectmodel of elk exemplaar wordt gemaakt op basis van een waarnemer, zijn hun levensduur onafhankelijk. Een toepassing kan een waarnemer verwijderen en het objectmodel of de instantie blijven gebruiken.
ObjectQuery
Een ObjectQuery vertelt een objectobator hoe objecten van een bepaald model kunnen worden gevonden. Het biedt de volgende niet-instelbare parameters, waarvan de standaardwaarden kunnen worden opgehaald uit een objectmodel.
MinSurfaceCoverage
De eigenschap MinSurfaceCoverage geeft de waarde aan die moet worden gezien als een exemplaar zoals gedetecteerd.
Voor elke objectkandidaat berekent een waarnemer de verhouding van overlappende oppervlakken tussen getransformeerd objectmodel en de scène. Vervolgens wordt deze kandidaat alleen gerapporteerd wanneer de dekkingsverhouding boven een bepaalde drempelwaarde ligt.
IsExpectedToBeStandingOnGroundPlane
De eigenschap IsExpectedToBeStandingOnGroundPlane geeft aan of het doelobject naar verwachting op het grondvlak staat.
Een grondvlak is de laagste horizontale vloer in het zoekgebied. Het biedt een goede beperking voor de mogelijke objecthoudingen. Als u deze vlag inschakelt, wordt de waarnemer begeleid bij het schatten van de houding in een beperkte ruimte en kan de nauwkeurigheid worden verbeterd. Deze parameter wordt genegeerd als het model niet op het grondvlak moet staan.
ExpectedMaxVerticalOrientationInDegrees
De eigenschap ExpectedMaxVerticalOrientationInDegrees geeft de verwachte maximumhoek aan in graden tussen de richting van een objectexemplaren en de zwaartekracht.
Deze parameter biedt een andere beperking voor de richting omhoog van een geschatte houding. Als een object bijvoorbeeld up-right is, kan deze parameter 0 zijn. Objectankers moeten geen objecten detecteren die afwijken van het model. Als een model up-right is, detecteert het geen exemplaar dat side-down is ingesteld. Er wordt een nieuw model gebruikt voor de indeling naast elkaar. Dezelfde regel geldt voor de articulatie.
MaxScaleChange
De eigenschap MaxScaleChange geeft de maximale wijziging van de objectschaal aan (binnen 0 ~ 1) met betrekking tot ruimtelijke toewijzing. De geschatte schaal wordt toegepast op getransformeerde hoekpunten van objecten gecentreerd op oorsprong en as uitgelijnd. Geschatte schalen zijn mogelijk niet de werkelijke schaal tussen een CAD-model en de fysieke weergave, maar sommige waarden waarmee de app een objectmodel dicht bij ruimtelijke toewijzing op het fysieke object kan weergeven.
SearchAreas
De eigenschap SearchAreas geeft een matrix van ruimtelijke grenzen aan waar objecten moeten worden gevonden.
De waarnemer zoekt naar objecten in de samenvoegruimte van alle zoekgebieden die zijn opgegeven in een query. In deze release retourneren we maximaal één object met het hoogste vertrouwen om de latentie te verminderen.
ObjectInstance
Een ObjectInstance vertegenwoordigt een hypothetische positie waarbij een exemplaar van een bepaald model zich in het HoloLens-coördinaatsysteem kan bevinden. Elke instantie wordt geleverd met een SurfaceCoverage
eigenschap om aan te geven hoe goed de geschatte houding is.
Er wordt een exemplaar gemaakt door de aanroepmethode aan te roepen ObjectObserver.DetectAsync
en vervolgens automatisch op de achtergrond bijgewerkt wanneer deze actief is. Een toepassing kan luisteren naar de gewijzigde status van een bepaald exemplaar of de traceringsmodus wijzigen om de update te onderbreken/hervatten. Een exemplaar wordt automatisch verwijderd uit de waarnemer wanneer het bijhouden verloren gaat.
ObjectDiagnosticsSession
ObjectDiagnosticSession registreert diagnostische gegevens en schrijft gegevens naar een archief.
Een diagnostisch archief bevat de scènepuntwolk, de status van de waarnemer en informatie over de modellen. Deze informatie is handig om mogelijke runtimeproblemen te identificeren. Zie de veelgestelde vragen voor meer informatie.
Runtime SDK-gebruik en -details
In deze sectie vindt u de basisbeginselen van het gebruik van de Runtime-SDK. Het geeft u voldoende context om door de voorbeeldtoepassingen te bladeren om te zien hoe Object Anchors holistisch wordt gebruikt.
Initialisatie
Toepassingen moeten de ObjectObserver.IsSupported()
API aanroepen om te bepalen of Object Anchors op het apparaat wordt ondersteund voordat ze worden gebruikt. Als de ObjectObserver.IsSupported()
API wordt geretourneerd false
, controleert u of de toepassing de spatialPerception-mogelijkheid heeft ingeschakeld en/of upgradet naar het nieuwste HoloLens-besturingssysteem.
using Microsoft.Azure.ObjectAnchors;
if (!ObjectObserver.IsSupported())
{
// Handle the error
}
// This call should grant the access we need.
ObjectObserverAccessStatus status = await ObjectObserver.RequestAccessAsync();
if (status != ObjectObserverAccessStatus.Allowed)
{
// Handle the error
}
Vervolgens maakt de toepassing een objectobnemer en laadt de benodigde modellen die zijn gegenereerd door de Object Anchors-modelconversieservice.
using Microsoft.Azure.ObjectAnchors;
// Note that you need to provide the Id, Key and Domain for your Azure Object
// Anchors account.
Guid accountId = new Guid("[your account id]");
string accountKey = "[your account key]";
string accountDomain = "[your account domain]";
AccountInformation accountInformation = new AccountInformation(accountId, accountKey, accountDomain);
ObjectAnchorsSession session = new ObjectAnchorsSession(accountInformation);
ObjectObserver observer = session.CreateObjectObserver();
// Load a model into a byte array. The model could be a file, an embedded
// resource, or a network stream.
byte[] modelAsBytes;
ObjectModel model = await observer.LoadObjectModelAsync(modelAsBytes);
// Note that after a model is loaded, its vertices and normals are transformed
// into a centered coordinate system for the ease of computing the object pose.
// The rigid transform can be retrieved through the `OriginToCenterTransform`
// property.
De toepassing maakt een query om exemplaren van dat model binnen een ruimte te detecteren.
#if WINDOWS_UWP || DOTNETWINRT_PRESENT
#define SPATIALCOORDINATESYSTEM_API_PRESENT
#endif
using Microsoft.Azure.ObjectAnchors;
using Microsoft.Azure.ObjectAnchors.SpatialGraph;
using Microsoft.Azure.ObjectAnchors.Unity;
using UnityEngine;
// Get the coordinate system.
SpatialGraphCoordinateSystem? coordinateSystem = null;
#if SPATIALCOORDINATESYSTEM_API_PRESENT
SpatialCoordinateSystem worldOrigin = ObjectAnchorsWorldManager.WorldOrigin;
if (worldOrigin != null)
{
coordinateSystem = await Task.Run(() => worldOrigin.TryToSpatialGraph());
}
#endif
if (!coordinateSystem.HasValue)
{
Debug.LogError("no coordinate system?");
return;
}
// Get the search area.
SpatialFieldOfView fieldOfView = new SpatialFieldOfView
{
Position = Camera.main.transform.position.ToSystem(),
Orientation = Camera.main.transform.rotation.ToSystem(),
FarDistance = 4.0f, // Far distance in meters of object search frustum.
HorizontalFieldOfViewInDegrees = 75.0f, // Horizontal field of view in
// degrees of object search frustum.
AspectRatio = 1.0f // Aspect ratio (horizontal / vertical) of object search
// frustum.
};
ObjectSearchArea searchArea = ObjectSearchArea.FromFieldOfView(coordinateSystem.Value, fieldOfView);
// Optionally change the parameters, otherwise use the default values embedded
// in the model.
ObjectQuery query = new ObjectQuery(model);
query.MinSurfaceCoverage = 0.2f;
query.ExpectedMaxVerticalOrientationInDegrees = 1.5f;
query.MaxScaleChange = 0.1f;
query.SearchAreas.Add(searchArea);
// Detection could take a while, so we run it in a background thread.
IReadOnlyList<ObjectInstance> detectedObjects = await observer.DetectAsync(query);
Standaard wordt elk gedetecteerd exemplaar automatisch bijgehouden door de waarnemer. We kunnen deze exemplaren desgewenst bewerken door de traceringsmodus te wijzigen of te luisteren naar de gewijzigde gebeurtenis van de status.
using Microsoft.Azure.ObjectAnchors;
foreach (ObjectInstance instance in detectedObjects)
{
// Supported modes:
// "LowLatencyCoarsePosition" - Consumes less CPU cycles thus fast to
// update the state.
// "HighLatencyAccuratePosition" - Uses the device's camera and consumes more CPU
// cycles thus potentially taking longer
// time to update the state.
// "Paused" - Stops to update the state until mode
// changed to low or high.
instance.Mode = ObjectInstanceTrackingMode.LowLatencyCoarsePosition;
// Listen to state changed event on this instance.
instance.Changed += InstanceChangedHandler;
// Optionally dispose an instance if not interested in it.
// instance.Dispose();
}
In de gewijzigde statusgebeurtenis kunnen we de meest recente status opvragen of een exemplaar verwijderen als het bijhouden is verloren.
using Microsoft.Azure.ObjectAnchors;
void InstanceChangedHandler(object sender, ObjectInstanceChangedEventArgs args)
{
// Try to query the current instance state.
ObjectInstanceState state = sender.TryGetCurrentState();
if (state != null)
{
// Process latest state.
// An object pose includes rotation and translation, applied in
// the same order to the object model in the centered coordinate system.
}
else
{
// This object instance is lost for tracking, and will never be recovered.
// The caller can detach the Changed event handler from this instance
// and dispose it.
}
}
Een toepassing kan eventueel ook één of meerdere diagnostische sessies vastleggen voor offline foutopsporing.
using Microsoft.Azure.ObjectAnchors;
using Microsoft.Azure.ObjectAnchors.Diagnostics;
string diagnosticsFolderPath = Windows.Storage.ApplicationData.Current.TemporaryFolder.Path;
const uint maxSessionSizeInMegaBytes = uint.MaxValue;
// Recording starts on the creation of a diagnostics session.
ObjectDiagnosticsSession diagnostics = new ObjectDiagnosticsSession(observer, maxSessionSizeInMegaBytes);
// Wait for the observer to do a job.
// Application can report some **pseudo ground-truth** pose for an instance
// acquired from other means.
diagnostics.ReportActualInstanceLocation(instance, coordinateSystem, Vector3.Zero, Quaternion.Identity);
// Close a session and write the diagnostics into an archive at specified location.
await diagnostics.CloseAsync(System.IO.Path.Combine(diagnosticsFolderPath, "diagnostics.zip"));
Ten slotte brengen we resources vrij door alle objecten op te werpen.
using Microsoft.Azure.ObjectAnchors;
foreach (ObjectInstance instance in activeInstances)
{
instance.Changed -= InstanceChangedHandler;
instance.Dispose();
}
model.Dispose();
observer.Dispose();