I'm experimenting the same problem with cloud recognition and I followed all the tips exposed here.
Development OS: Mac OS X Mountain Lion
Mobile OS and Version: Android 4.4.2
Mobile Device Manufacturer and Model name: HTC One M7
Do the Vuforia Sample Applications show the same behavior?: exactly the same behavior
I am using Vuforia Unity Extension with last published cloud sample (cloudreco-3-0-10.unitypackage).
The only changes I've made in the sample are:
- debug line to know the times the function OnNewSearchResult is called.
- a line to stop TargetFinder as you explain in this other thread, as I didn't see that change on the provided code ( https://developer.vuforia.com/forum/cloud-recognition/cloud-reco-samples-reco-count )
/*==============================================================================
Copyright (c) 2012-2014 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
==============================================================================*/
using System;
using UnityEngine;
/// <summary>
/// This MonoBehaviour implements the Cloud Reco Event handling for this sample.
/// It registers itself at the CloudRecoBehaviour and is notified of new search results as well as error messages
/// The current state is visualized and new results are enabled using the TargetFinder API.
/// </summary>
public class CloudRecoEventHandler : MonoBehaviour, ICloudRecoEventHandler
{
#region PRIVATE_MEMBER_VARIABLES
// ImageTracker reference to avoid lookups
private ImageTracker mImageTracker;
private ContentManager mContentManager;
// the parent gameobject of the referenced ImageTargetTemplate - reused for all target search results
private GameObject mParentOfImageTargetTemplate;
private CloudRecoBehaviour cloudRecoBehaviour;
#endregion // PRIVATE_MEMBER_VARIABLES
#region EXPOSED_PUBLIC_VARIABLES
/// <summary>
/// can be set in the Unity inspector to reference a ImageTargetBehaviour that is used for augmentations of new cloud reco results.
/// </summary>
public ImageTargetBehaviour ImageTargetTemplate;
#endregion
#region ICloudRecoEventHandler_IMPLEMENTATION
/// <summary>
/// called when TargetFinder has been initialized successfully
/// </summary>
public void OnInitialized()
{
// get a reference to the Image Tracker, remember it
mImageTracker = TrackerManager.Instance.GetTracker<ImageTracker>();
mContentManager = (ContentManager)FindObjectOfType(typeof(ContentManager));
}
/// <summary>
/// visualize initialization errors
/// </summary>
public void OnInitError(TargetFinder.InitState initError)
{
switch (initError)
{
case TargetFinder.InitState.INIT_ERROR_NO_NETWORK_CONNECTION:
ErrorMsg.New("Network Unavailable", "Please check your internet connection and try again.", RestartApplication);
break;
case TargetFinder.InitState.INIT_ERROR_SERVICE_NOT_AVAILABLE:
ErrorMsg.New("Service Unavailable", "Failed to initialize app because the service is not available.");
break;
}
}
/// <summary>
/// visualize update errors
/// </summary>
public void OnUpdateError(TargetFinder.UpdateState updateError)
{
switch (updateError)
{
case TargetFinder.UpdateState.UPDATE_ERROR_AUTHORIZATION_FAILED:
ErrorMsg.New("Authorization Error","The cloud recognition service access keys are incorrect or have expired.");
break;
case TargetFinder.UpdateState.UPDATE_ERROR_NO_NETWORK_CONNECTION:
ErrorMsg.New("Network Unavailable","Please check your internet connection and try again.");
break;
case TargetFinder.UpdateState.UPDATE_ERROR_PROJECT_SUSPENDED:
ErrorMsg.New("Authorization Error","The cloud recognition service has been suspended.");
break;
case TargetFinder.UpdateState.UPDATE_ERROR_REQUEST_TIMEOUT:
ErrorMsg.New("Request Timeout","The network request has timed out, please check your internet connection and try again.");
break;
case TargetFinder.UpdateState.UPDATE_ERROR_SERVICE_NOT_AVAILABLE:
ErrorMsg.New("Service Unavailable","The service is unavailable, please try again later.");
break;
case TargetFinder.UpdateState.UPDATE_ERROR_TIMESTAMP_OUT_OF_RANGE:
ErrorMsg.New("Clock Sync Error","Please update the date and time and try again.");
break;
case TargetFinder.UpdateState.UPDATE_ERROR_UPDATE_SDK:
ErrorMsg.New("Unsupported Version","The application is using an unsupported version of Vuforia.");
break;
}
}
/// <summary>
/// when we start scanning, unregister Trackable from the ImageTargetTemplate, then delete all trackables
/// </summary>
public void OnStateChanged(bool scanning)
{
if (scanning)
{
// clear all known trackables
mImageTracker.TargetFinder.ClearTrackables(false);
// hide the ImageTargetTemplate
mContentManager.ShowObject(false);
}
}
/// <summary>
/// Handles new search results
/// </summary>
/// <param name="targetSearchResult"></param>
public void OnNewSearchResult(TargetFinder.TargetSearchResult targetSearchResult)
{
Debug.Log("New Search Result: " + targetSearchResult.TargetName);
// This code demonstrates how to reuse an ImageTargetBehaviour for new search results and modifying it according to the metadata
// Depending on your application, it can make more sense to duplicate the ImageTargetBehaviour using Instantiate(),
// or to create a new ImageTargetBehaviour for each new result
// Vuforia will return a new object with the right script automatically if you use
// TargetFinder.EnableTracking(TargetSearchResult result, string gameObjectName)
//Check if the metadata isn't null
if(targetSearchResult.MetaData == null)
{
return;
}
// First clear all trackables
mImageTracker.TargetFinder.ClearTrackables(false);
// enable the new result with the same ImageTargetBehaviour:
ImageTargetBehaviour imageTargetBehaviour = mImageTracker.TargetFinder.EnableTracking(targetSearchResult, mParentOfImageTargetTemplate) as ImageTargetBehaviour;
// ADD THIS TO STOP CLOUD SCAN
cloudRecoBehaviour.CloudRecoEnabled = false;
//if extended tracking was enabled from the menu, we need to start the extendedtracking on the newly found trackble.
if(CloudRecognitionUIEventHandler.ExtendedTrackingIsEnabled)
{
imageTargetBehaviour.ImageTarget.StartExtendedTracking();
}
}
#endregion // ICloudRecoEventHandler_IMPLEMENTATION
#region UNTIY_MONOBEHAVIOUR_METHODS
/// <summary>
/// register for events at the CloudRecoBehaviour
/// </summary>
void Start()
{
// look up the gameobject containing the ImageTargetTemplate:
mParentOfImageTargetTemplate = ImageTargetTemplate.gameObject;
// intialize the ErrorMsg class
ErrorMsg.Init();
// register this event handler at the cloud reco behaviour
cloudRecoBehaviour = GetComponent<CloudRecoBehaviour>();
if (cloudRecoBehaviour)
{
cloudRecoBehaviour.RegisterEventHandler(this);
}
}
/// <summary>
/// draw the sample GUI and error messages
/// </summary>
void OnGUI()
{
// draw error messages in case there were any
ErrorMsg.Draw();
}
#endregion UNTIY_MONOBEHAVIOUR_METHODS
#region PRIVATE_METHODS
// callback for network-not-available error message
private void RestartApplication()
{
Application.LoadLevel("Vuforia-1-About");
}
#endregion PRIVATE_METHODS
}
In order to test this clearly, I made a new cloud database and created 3 new targets and recorded the whole process.
The following link contains the recorded video: http://youtu.be/VGWEITkgokg
I also attach the final console capture, where you will see that the first target (Test1) calls OnNewSearchResult twice, which I don't understand why but happens all the time I restart the application, even in Unity Editor, and the two other targets call the function only once.
If you check the other image, the count capture total is 5 and it should be 3 (or 4 having into account that first target is always being called twice)
I've experimented weird recognition recounts in other occasions, having 3 or 4 extra recos on targets that I only recognised once.
Hope you can give me an answer.
Regards.
I've checked with our team and the common understanding of this is that the number of reco events (what you refer to as "the extra calls") is not necessarily mapped 1-to-1 with the number of times a New Search Result is reported to the client SDK API;
this is because, essentially (and as I had outlined in my previous answer), if the reported image target (Search Result) happens to be same target (within a short time frame), then the SDK will be "smart" enough to only report it once (so that your Application code only neds to handle one target).
So, the issue is about not confusing the "high-level" representation of recognized targets that the client SDK reports (in terms of Search Results API) with the "low-level" (Cloud-backend related) number of recos that actually reflects the "actual usage" of the Cloud service, and for which you are accounted.
However,
if you are thinkng that you would want / wish to have an additional API in the Vuforia SDK that simply reports the actual number of recognition events (as opposed to the Search Result reporting API), this is probably something that you could post in our Wish List, so that we could consider this enhancement for a future release of Vuforia.