PTCInc / vuforia-engine

Bug and feedback issue tracker for the Vuforia Engine SDK
https://developer.vuforia.com
20 stars 0 forks source link

There is no proper steps mentioned to prevent a continuously running vuCloudImageTargetObserverRegisterHandlers #141

Closed hiren-addweb closed 4 months ago

hiren-addweb commented 5 months ago

Troubleshooting Discrepant Reco Counts

Elaborate on your feedback or issue I wanted to stop tracking cloud queries when the object from the cloud is detected and cached locally. But didn't find a clear guide on how to do it. My entire setup is completely based on the Vuforia sample and I have integrated cloud reco functionality in it.

Describe the solution you'd like If there is a reference code sample or guide on stopping vuEngineRegisterStateHandler after the callback detects the cloud image target. it would be very helpful for the user and save unnecessary cloud recognition calls.

Describe possible alternatives you've considered Alternatively, if someone can guide me based on my code, that will also be best for me for now.

Additional Context

ptc-thesbyro commented 5 months ago

Hi @hiren-addweb,

I think you can deactivate the Cloud Image Target Observer to stop Vuforia Engine from searching for new targets.

You can for example do this after you create an Image Target with vuEngineCreateImageTargetObserverFromCloudObservation. Then if successful, call vuObserverDeactivate(observer) Then the handler won't get called anymore and any Image Targets created from the search results continue to work but have to be destroyed independently.

Hope it helps,

hiren-addweb commented 5 months ago

But in that case, if I shift my camera focus to another target image and want to run a query how it can be done? if you can guide me about that.

hiren-addweb commented 5 months ago
        VuCloudImageTargetCreationError creationError;
        if (vuEngineCreateCloudImageTargetObserver(mEngine, &mObjectObserver, &cloudImageTargetConfig, &creationError) != VU_SUCCESS){
            // handle observer creation errors
            switch (creationError){
                case VU_CLOUD_IMAGE_TARGET_CREATION_ERROR_NO_NETWORK_CONNECTION:
                    // handle the "NO NETWORK" error
                    return  false;
                    break;
            }
        }
        eventHandler = reinterpret_cast<void (*)(
                const VuObservationList *, void *)>(&recoEventHandler);
        AppController *clientdata = this;
        vuCloudImageTargetObserverRegisterHandlers(mObjectObserver, *eventHandler, AppController::queryErrorHandler, clientdata);
void
AppController::recoEventHandler(const VuObservationList *observations, AppController *clientData)
{
    int32_t numObservations = 0;
    clientData->mTracked = 1;
    clientData->eventHandler = nullptr;
    vuObservationListGetSize(observations, &numObservations);

    // iterate through all Cloud Image Target observations received via reco event
    for (int i = 0; i < numObservations; i++)
    {
        VuObservation *observation = nullptr;
        vuObservationListGetElement(observations, i, &observation);

        // read Cloud Image Target information
        VuCloudImageTargetObservationTargetInfo cloudImageTargetInfo;
        vuCloudImageTargetObservationGetTargetInfo(observation, &cloudImageTargetInfo);
        LOG("Cloud Image Target '%s' recognized", cloudImageTargetInfo.name);
        LOG("Cloud Image Target '%s' recognized", cloudImageTargetInfo.metadata);
        VuforiaWrapper wrapper;
        wrapper.receiveDataFromAppController(cloudImageTargetInfo.metadata);
        // create Image Target observer using Cloud Image Target observation
        VuImageTargetCloudObservationConfig cloudObservationConfig = vuImageTargetCloudObservationConfigDefault();
        cloudObservationConfig.observation = observation;
        cloudObservationConfig.activate = VU_TRUE; // automatically activate if engine is running

        // VuObserver *targetObserver = nullptr;
        VuImageTargetCloudObservationCreationError creationError;
        if (vuEngineCreateImageTargetObserverFromCloudObservation(clientData->mEngine, &clientData->mObjectObserver, &cloudObservationConfig,
                                                                  &creationError) != VU_SUCCESS)
        {
            // error handling
            continue;
        }
    }
}

this is how I currently use observer...

hiren-addweb commented 4 months ago

@ptc-thesbyro When I call "vuObserverDeactivate(observer)" it stops tracking objects altogether. I'm not sure why. If you could provide a proper example or guidance for implementing it with best practices, it would be very helpful for me.

hiren-addweb commented 4 months ago

update:

I managed to deactivateObserver using the following code: vuObserverDeactivate(clientData->mCloudImageTargetObserver);

Now I need to reactivate the observer if the target is different from the current. ( meaning my focus is now on another image, I wanted to detect.) Regarding that below are a couple of questions in my mind that I need help with.

For a single object, it is working fine. Thanks for this valuable insight and suggestion.

ptc-thesbyro commented 4 months ago

Hi @hiren-addweb,

Let's slow down a little. This GitHub issue tracker and tags are for giving feedback, reporting bugs and issues, requesting features, and asking for documentation improvements. I feel we're getting sidetracked from the topic on this thread, which was stopping Engine from searching for new results.

To get help with debugging code, I recommend using StackOverflow with the tag [Vuforia].

Now, to your latest questions. If I shift my camera focus to another target image and want to run a query how it can be done? - Well, you shouldn't deactivate the Cloud Image Target Observer if you actually want to continue getting results on new images. How can I manage to do that? - Keep your Cloud Image Target Observer activated. if I detect the same image again how do I get metadata of that particular image will it count as another reco or is there any other way to do it? - If you detect cloud image A, move to cloud image B, get a successful query, and then move back again to A and detect it, that counts as three recos. Vuforia Engine caches the previous reco result. This means that querying cloud image A, moving away, and returning to cloud image A will not count as a reco. If you successfully query a new cloud image (B), it will replace cloud image A in the cache and counts as a reco.

Let me know if that answers your questions.

I apologize for not being able to help with debugging your application code.

Hope it helps,

hiren-addweb commented 4 months ago

Apologies for the numerous comments.

Lots of things are clear to me now... Just a few last things and I am all good.

Sorry again for the lots of comments. Your insight and guidance on the matter helped me a lot.

Thank you for your insightful answer.

ptc-thesbyro commented 4 months ago

No apologies needed. I'm happy to hear that you are getting a better understanding from this exchange.

You can most certainly combine cloud image databases and local Image Target Databases. The only difference between the two is the creation of the Image Target Observer. One is when a certain image is detected that matches against your cloud database, and the other is by getting the targetName of an image stored in a local database. Both methods end up giving you an Image Target Observer. You can also track Image Targets simultaneously if that suits your use case.

I'm not sure what the best approach is here, and, unfortunately, we do not have documentation or API for such a specific use case that I know of. My best guess is that you would use the Vuforia Web Services to update the target, setting the cloud image to inactive once it has been detected and made into an Image Target Observer. Though, this requires more work to integrate web requests in your application.

hiren-addweb commented 4 months ago

is there any method using which I can put my cloud dataset data into my local dataset once the image is detected? So that way the object detection performance will be faster compared to the cloud when the user scans that image again?

otherwise, I am all good.

ptc-thesbyro commented 4 months ago

You can look into creating the Image target Observer directly from the camera with vuEngineCreateImageTargetObserverFromBufferConfig(), or from a file: Create image targets at runtime. Then you will store the image in the local storage. I don't think there's a way to add cloud images to a local Image Target database.

It also depend if you want faster image tracking in a single session or have the app remember which targets it already detected over multiple sessions. A single session should be fine since an Image Target Observer is already created for the image; the (re)-detection and tracking should be instantaneous. For resuming or re-launching a new session, we only support that partly: See Continued AR experiences

hiren-addweb commented 4 months ago

Thank you @ptc-thesbyro for your valuable guidance. The issue can be marked as closed or resolved.