Object Tracker

An object tracker will follow detected objects during the intermediate frames between model executions and match existing objects to new detections. This reduces the possiblilty of duplication of recognitions for the same object in different frames, and can provide a smoother experience by updating an object's location more frequently than a model can execute.

To use an object tracker, call its onFrame() on each new frame and trackResults() on each model recognition result. The parameters for each method vary based on the tracker used, but the function of each remains the same.

onFrame() processes each new frame and updates the location of any currently tracked objects. trackResults() adds new objects to the tracker and finds a correlation between the new object and existing tracked objects to determine if they are the same object.

Note

At this time, we recommended using BasicObjectTracker for detections from RoadSignsModel and RoadHazardsModel.

The following provides an example of tracking using MultiBoxObjectTracker with detections from RoadBasicsModel:

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.HandlerThread;

import com.here.see.common.util.permission.AuthorizationException;
import com.here.see.livesense.RoadBasicsModel;
import com.here.see.livesense.domain.Recognition;
import com.here.see.livesense.tracker.MultiBoxObjectTracker;
import com.here.see.livesense.tracker.TrackedRecognition;

import java.io.IOException;
import java.util.List;

public class RecognitionWithTracking {
    private HandlerThread detectionThread;
    private Handler detectionHandler;
    private RoadBasicsModel roadBasicsModel;

    private volatile boolean isDetectionRunning = false;
    private MultiBoxObjectTracker objectTracker = new MultiBoxObjectTracker();
    // Frame sequence used by tracker to identify each frame
    private long timestamp = 0;

    public void init(Context context) {
        // Start background thread
        detectionThread = new HandlerThread("detection");
        detectionThread.start();
        detectionHandler = new Handler(detectionThread.getLooper());

        // Initialize model
        try {
            roadBasicsModel = new RoadBasicsModel(this, new RoadBasicsModel.Options());
        } catch (IOException e) {
            // Failed to initialize model
        } catch (AuthorizationException e) {
            // Missing or invalid credentials
        }
    }

    public void close() {
        if (detectionThread != null) {
            detectionThread.quitSafely();
            detectionThread = null;
            detectionHandler = null;
        }
        timestamp = 0;
        if (objectTracker != null) {
            objectTracker.close();
            objectTracker = new MultiBoxObjectTracker();
        }
    }

    /**
     * @param frame          RGBA8888 image
     * @param frameLuminance Luminance of frame (grayscale/Y of YUV Image)
     * @param frameRotation  Clockwise rotation to reach frame's natural orientation as a multiple of 90 degrees
     */
    public List<TrackedRecognition> recognizeWithTracking(Bitmap frame, byte[] frameLuminance, int frameRotation) {
        // Increment frame sequence
        timestamp++;
        // Get frame size
        int width = frame.getWidth();
        int height = frame.getHeight();
        int stride = width;
        // Send frame to tracker
        objectTracker.onFrame(
                width,
                height,
                stride,
                frameRotation,
                frameLuminance,
                timestamp);

        // Run detection if not currently doing so
        if (!isDetectionRunning) {
            runDetectionInBackground(frame, frameLuminance, frameRotation, timestamp);
        }
        // Return current list of tracked recognitions for further processing/display
        return objectTracker.getTrackedObjects();
    }

    private void runDetectionInBackground(final Bitmap frame, final byte[] frameLuminance, final int frameRotation, final long timestamp) {
        isDetectionRunning = true;
        // Start background task
        detectionHandler.post(() -> {
            // Perform detection
            List<Recognition> recognitions = roadBasicsModel.recognizeImage(frame, frameRotation, 0.6f);
            // Feed recognitions to tracker
            objectTracker.trackResults(recognitions, frameLuminance, timestamp);
            // Signal ready for new frame
            isDetectionRunning = false;
        });
    }
}

results matching ""

    No results matching ""