Description

Moved from Parent

Cloud Reco Samples - Reco Count

The Cloud Recognition samples of the SDK release 2.8.7 (native samples version 2.8.8, Unity samples version 2.8.9) show how to start a Cloud search for target recogniton, using a sample DB.

In particular, the samples make use of the TargetFinde::start() API, by which the sample will enter a search mode where your Cloud Database is scanned for a possible target match. See also these pages for more details on Cloud Reco API usage:

https://developer.vuforia.com/resources/dev-guide/cloud-recognition-feature

https://developer.vuforia.com/resources/dev-guide/cloud-recognition-unity

Note however that the samples in question do not stop the target finder explicitly, once a target has been detected.

As a consequence, the Cloud scanning process of the samples will keep running in the background even after a target has been recognized (and the target has been augmented); in such a context, as you move your device around (with respect to the target), additional recognition events might occur, and the "reco count" charged to the Cloud Database may increase accordingly.

 

While this has no consequences for the samples themselves, as they use a Cloud Account and Database specifically dedicated to the sample., you may want to consider adjusting the TargetfFinder start/stop application logic when building your app and/or when using the Cloud recognition samples with your own Cloud Database (i.e.e usinbg your own client access and secret keys), so that the reco count will only be increased when strictly required.

In particular, it is recommended to stop the TargetFinder as soon as a new TargetSearchResult is reported by the Vuforia API callbacks.

In the native sample code (see "VuforiaSamples-2-8-8", in the sub-package "com.qualcomm.vuforia.samples.VuforiaSamples.app.CloudRecognition", file CloudReco.java), you can stop the Cloud scan by adding a TargetFinder.stop() call in the onQCARUpdate(State state) method, as shown in this snippet:

if (result.getTrackingRating() > 0)
{
    Trackable trackable = finder.enableTracking(result);
                    
     finder.stop(); // ADD THIS LINE TO STOP CLOUD SCAN
                   
     if (mExtendedTracking)
         trackable.startExtendedTracking();
 }

Similarly, in the iOS VuforiaSamples-2-8-8, you can add a line of code finder::stop().

In Unity, the TargetFinder can either be stopped explicitly, using TargetFinder.Stop() API, or indirectly by disabling the CloudRecognition prefab object, in the OnNewSearchResult() callback, as shown in this C# snippet:

 

Cloud Reco - Using Target Metadata

 

This article highlights the meaning and usage best practices for Cloud Targets Metadata.

In Vuforia, every Cloud Image Target has an associated Metadata; a target metadata is nothing else than a custom (user-defined) string, i.e. a blob of text that you can fill with any text you like.

Therefore, you can use the metadata just as a way to contain some information about the target, that your application will be able to process using some custom logic.

Just as an example, your application might use the metadata string to represent some of the following:

  • some simple text message (like “Hello, I am your image target XYZ”) that you want to display on the screen of your device when the target is detected
  • a URL pointing to a 3D model stored on a server (for instance something like “http://my_server/my_models/my_model_01.obj”), so that for each different image target, your application may use that URL to connect to a specific server and retrieve (and render) a specific 3D model as the augmentation for that image target;
  • the filename of a 3D model stored on your device local storage or SD card (essentially the same scenario as the previous point, but using local storage instead of a remote server);
  • the URL of a specific video that you want your application to play when the image target is recognized;
  • the URL of some other type of data/content stored in a server database
  • more in general, some special string that your application is able to process and use to perform specific actions

 

How do I create a metadata and how do I associate it to a Cloud target ?

Metadata can be uploaded together with an image target at the time you create the target itself in your Cloud Database; or you can also update the metadata of an existing target, at a later time; in both case, you can use the online TargetManager, as explained here:

https://developer.vuforia.com/resources/dev-guide/managing-targets-cloud-database-using-target-manager

Or you can proceed programmatically though the VWS API, as explained here:

https://developer.vuforia.com/resources/dev-guide/managing-targets-cloud-database-using-developer-api

 

The relevant API to retrieve the metadata of a target in your mobile application (when the target is detected) is:

  • Native SDK:          TargetSearchResult::getMetadata()
  • Unity Extension:   TargetSearchResult.Metadata()

Sample code:

For a reference sample code in native, see the CloudRecognition.cpp file in the CloudRecognition sample project.

For a reference sample code in Unity, see the CloudRecoEventHandler.cs script (attached to the CloudRecognition prefab) in the CloudRecognition sample; in particular, the OnNewSearchResult method shows how to get a targetSearchResult object (from which you can then get the metadata, as shown in the example code).

VWS Authentication

Hello,

I have an authentication failure on Postman.

Maybe it's the fault of my signature.

I created a Python code to generate the signature.

Here is the code:

----------------------------------------------------------------------------------

import hmac import hashlib import base64 import urllib import datetime

# Your VWS secret key vws_secret_key = "704ed8658cd2bfc566bcabb3e84511b55221dd23"

# The HTTP method of your request http_verb = "GET"

# The Content-MD5 of your request body content_md5 = "d41d8cd98f00b204e9800998ecf8427e"

# The Content-Type of your request content_type = "application/json"

# The current date and time date = datetime.datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT")

# The path of your request request_path = " https://vws.vuforia.com/duplicates/bb6ac8156fe2498f863d49bc2592a3ff"

# Concatenate the elements of the StringToSign string_to_sign = http_verb + "\n" + content_md5 + "\n" + content_type + "\n" + date + "\n" + request_path

# Sign the StringToSign using the VWS secret key and the HMAC-SHA1 algorithm signature = hmac.new(vws_secret_key.encode(), string_to_sign.encode(), hashlib.sha1)

# Encode the signature in base64 vws_signature = base64.b64encode(signature.digest()).decode()

print(date) print(vws_signature)

-----------------------------------------------------------------------------------

Can you help me please ?

Thanks

Hey there,

 

I won't be able to review your code, but if you can share the failure transaction code, I can validate the logs with the team.

 

Kind regards,

Patrick Scheper

Vuforia Engine Product Manager

EnableTracking fails syntax checking.

Platform

The function EnableTracking fails syntax checking.

The simple example code at;

https://library.vuforia.com/cloud-recognition/working-cloud-recognition#unity

Uses this function in the method OnNewSearchResult() yet this does not pass syntax checking.

Unity 2021.3.1f1

Vuforia Engine Version 10.7.2

Thanks in advance,

E

Error Vuforia Cloud

using System.Collections; using System.Collections.Generic; using UnityEngine; using Vuforia;

public class SimpleCloudHandler : MonoBehaviour, ICloudRecoEventHandler {     private CloudRecoBehaviour mCloudRecoBehaviour;     private bool mIsScanning = false;     private string mTargetMetadata = "";     public ImageTargetBehaviour ImageTargetTemplate;     private ObjectTracker mImageTracker;

    // Register cloud reco callbacks     void Start()     {         CloudRecoBehaviour cloudRecoBehaviour = GetComponent<CloudRecoBehaviour>();         if (cloudRecoBehaviour)         {             cloudRecoBehaviour.RegisterEventHandler(this);         }

        mCloudRecoBehaviour = cloudRecoBehaviour;     }     //Unregister cloud reco callbacks when the handler is destroyed

    public void OnInitialized()     {         mImageTracker = (ObjectTracker)TrackerManager.Instance.GetTracker<ObjectTracker>();     }     public void OnInitError(TargetFinder.InitState initError)     {

    }     public void OnUpdateError(TargetFinder.UpdateState updateError)     {

    }     public void OnStateChanged(bool scanning)     {         mIsScanning = scanning;         if (scanning)         {             // clear all known trackables             ObjectTracker tracker = TrackerManager.Instance.GetTracker<ObjectTracker>();             tracker.GetTargetFinder<ImageTargetFinder>().ClearTrackables(false);         }     }

    // Here we handle a cloud target recognition event     public void OnNewSearchResult(TargetFinder.TargetSearchResult targetSearchResult)     {         GameObject newImageTarget = Instantiate(ImageTargetTemplate.gameObject) as GameObject;

        GameObject augmentation = null;         string model_name = targetSearchResult.MetaData;

        if (augmentation != null)             augmentation.transform.parent = newImageTarget.transform;

        ImageTargetAbstractBehaviour ImageTargetBehaviour = mImageTracker.TargetFinder.EnableTracking(targetSearchResult, newImageTarget);

        Debug.Log("Metadata value is " + model_name);         mTargetMetadata = model_name;

        switch (model_name)         {             case "left":                 Destroy(ImageTargetBehaviour.gameObject.transform.Find("right").gameObject);                 break;

            case "right":                 Destroy(ImageTargetBehaviour.gameObject.transform.Find("left").gameObject);                 break;         }         if (!mIsScanning)         {             mCloudRecoBehaviour.CloudRecoEnabled = true;         }

        void OnGUI()         {             GUI.Box(new Rect(100, 200, 200, 50), "Metadata: " + mTargetMetadata);         }

    }

    public void OnInitialized(TargetFinder targetFinder)     {         throw new System.NotImplementedException();     } }

Attachment

Target Image field

Hello,

 

I just have a quick question.

After applying the script 'SimpleCloudRecoEventHandler' I don't have the input field for my reference image.

This is my script :

using UnityEngine;

using Vuforia;

public class SimpleCloudRecoEventHandler : MonoBehaviour {     private CloudRecoBehaviour mCloudRecoBehaviour;     private bool mIsScanning = false;     private string mTargetMetadata = "";     public ImageTargetBehaviour ImageTargetTemplate;

    // Register cloud reco callbacks     void Awake()     {         mCloudRecoBehaviour = GetComponent<CloudRecoBehaviour>();         mCloudRecoBehaviour.RegisterOnInitializedEventHandler(OnInitialized);         mCloudRecoBehaviour.RegisterOnInitErrorEventHandler(OnInitError);         mCloudRecoBehaviour.RegisterOnUpdateErrorEventHandler(OnUpdateError);         mCloudRecoBehaviour.RegisterOnStateChangedEventHandler(OnStateChanged);         mCloudRecoBehaviour.RegisterOnNewSearchResultEventHandler(OnNewSearchResult);     }     //Unregister cloud reco callbacks when the handler is destroyed     void OnDestroy()     {         mCloudRecoBehaviour.UnregisterOnInitializedEventHandler(OnInitialized);         mCloudRecoBehaviour.UnregisterOnInitErrorEventHandler(OnInitError);         mCloudRecoBehaviour.UnregisterOnUpdateErrorEventHandler(OnUpdateError);         mCloudRecoBehaviour.UnregisterOnStateChangedEventHandler(OnStateChanged);         mCloudRecoBehaviour.UnregisterOnNewSearchResultEventHandler(OnNewSearchResult);     }     public void OnInitialized(TargetFinder targetFinder)     {         Debug.Log("Cloud Reco initialized");     }     public void OnInitError(TargetFinder.InitState initError)     {         Debug.Log("Cloud Reco init error " + initError.ToString());     }     public void OnUpdateError(TargetFinder.UpdateState updateError)     {         Debug.Log("Cloud Reco update error " + updateError.ToString());     }     public void OnStateChanged(bool scanning)     {         mIsScanning = scanning;         if (scanning)         {             // clear all known trackables             var tracker = TrackerManager.Instance.GetTracker<ObjectTracker>();             tracker.GetTargetFinder<ImageTargetFinder>().ClearTrackables(false);         }     }     // Here we handle a cloud target recognition event     public void OnNewSearchResult(TargetFinder.TargetSearchResult targetSearchResult)     {         TargetFinder.CloudRecoSearchResult cloudRecoSearchResult =             (TargetFinder.CloudRecoSearchResult)targetSearchResult;         // do something with the target metadata         mTargetMetadata = cloudRecoSearchResult.MetaData;         // stop the target finder (i.e. stop scanning the cloud)         mCloudRecoBehaviour.CloudRecoEnabled = false;         // Build augmentation based on target         if (ImageTargetTemplate)         {             // enable the new result with the same ImageTargetBehaviour:             ObjectTracker tracker = TrackerManager.Instance.GetTracker<ObjectTracker>();             tracker.GetTargetFinder<ImageTargetFinder>().EnableTracking(targetSearchResult, ImageTargetTemplate.gameObject);         }     }

    void OnGUI()     {         // Display current 'scanning' status         GUI.Box(new Rect(100, 100, 200, 50), mIsScanning ? "Scanning" : "Not scanning");         // Display metadata of latest detected cloud-target         GUI.Box(new Rect(100, 200, 200, 50), "Metadata: " + mTargetMetadata);         // If not scanning, show button         // so that user can restart cloud scanning         if (!mIsScanning)         {             if (GUI.Button(new Rect(100, 300, 200, 50), "Restart Scanning"))             {                 // Restart TargetFinder                 mCloudRecoBehaviour.CloudRecoEnabled = true;             }         }     } }

 

I have this error  Assets\Editor\SimpleCloudRecoEventHandler.cs(53,35): error CS0246: The type or namespace name 'TargetFinder' could not be found (are you missing a using directive or an assembly reference?)

Can anyone tell me why?

Thanks

Hey there,

 

You're experiencing the same issue as someone else on the forums. Please check my response here: https://developer.vuforia.com/forum/cloud-recognition/error-vuforia-cloud#comment-74491

I will close the thread, but please create a new one if needed.

Java example, please!

Greetings fellow developers,

I'm trying to perform image recognition query as described in https://library.vuforia.com/articles/Solution/How-To-Perform-an-Image-Recognition-Query with Java. I've found some examples, but all of them are resulting in {"transaction_id":"3a0b97803864427aba06616a6ef1ca44","result_code":"AuthenticationFailure"}. I've tried to use client and server key and secret and nothing helped.

Can anyone help me and provide me the working Java example? 

Thanks in advance,

Kuba

Poor success rate

I uploaded 10k images and then resubmitted each one as a query to see how many would be properly identified by Vuforia.  I was disappoint to find that it only recognized approx 25% of the identical images!!!  Am I perhaps doing something wrong?  Does recognition get better with bigger images?  Thx

Hey Patrick,

All of the images are more or less unique.  They are pre-existing images so I don't have much control over the contrast.  The average image size is 45k.

Cloud Recognition & Rails

I'm struggling to encode the body of my Image Recognition query with Ruby on Rails.  Has anyone done this and can you help? 

I have been successful with Python and even copied the signatures and encoded file from Python and successfully made a query from Rails - I just can't get the encoding to work.

Thanks!

Worldspace UI on Cloud target recognition

Hi,

I am trying to place worldspace Canvas with UI text elements on recognition of Cloud image target. But somehow, it is not visible on recognition. Is this the scaling issue?

Hello,

Please review the Vuforia Books Sample in the Unity Asset Store for Cloud Reco UI best practices:

https://assetstore.unity.com/packages/templates/packs/vuforia-books-sample-102254

Thanks,

Vuforia Engine Support