1 # Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
3 @page imageprocessing_tracking_usecase1 Single Camera Template Tracking
5 @note SW Release Applicability: This tutorial is applicable to modules in both **NVIDIA DriveWorks** and **NVIDIA DRIVE Software** releases.
7 The tutorial shows the general structure of a program that uses the 2D template tracker to track templates in a single camera.
9 #### Initialize template array on both CPU and GPU
11 `contextHandle` is assumed to be previously initialized `::dwContextHandle_t`.
13 dwTemplateArray_create(&templateCPU, maxFeatureCount,
14 DW_FEATURE2D_MEMORY_TYPE_CPU, contextHandle);
15 dwTemplateArray_create(&templateGPU, maxFeatureCount,
16 DW_FEATURE2D_MEMORY_TYPE_CUDA, contextHandle);
20 #### Initialize template tracker parameters with default values
23 dwTemplateTrackerParameters params = {};
24 dwTemplateTracker_initDefaultParams(¶ms);
27 #### Modify parameters according to tracking requirements
29 `imageProps` is the `dwImageProperties` structure of image to be tracked
32 dwImage_getPixelType(¶ms.pxlType, imageProps.format);
33 params.validWidth = DW_MAX_TEMPLATE2D_SIZE;
34 params.validHeight = DW_MAX_TEMPLATE2D_SIZE;
38 Select on which processor the tracker should be performed on. Possible options are
39 `DW_PROCESSOR_TYPE_GPU`, `DW_PROCESSOR_TYPE_PVA_0`, `DW_PROCESSOR_TYPE_PVA_1`.
40 Note that PVA is only supported on NVIDIA DRIVE<sup>™</sup> platforms.
41 Moreover, if the processor is set to PVA, the image dimensions need to be provided at initialization.
44 params.processorType = DW_PROCESSOR_TYPE_PVA_0;
45 params.imageWidth = 1280;
46 params.imageHeight = 800;
49 #### Initialize template tracker with given parameters and bind output
52 dwTemplateTracker_initialize(&tracker, ¶ms, 0, contextHandle);
55 Create 2 image pyramids as detection/tracking input: one is current, one is
56 previous, the 2 pyramids work as a double buffer (or ping-pong buffer). They
57 swap each other after each detection/tracking cycle. So new frame will always
58 be read into pyramidCurrent and the previous frame will be stored to
61 `dwPyramid_create` only creates pyramid image and allocates memory, pyramid will be filled in `dwImageFilter_computePyramid`. Top level (level 0) in pyramid is always the same size as original input image.
63 `inputImageProps.width`, `inputImageProps.height` are the same in tracker/detector initialization
65 `imagePxlType` should be got from `dwImage_getPixelType(inputImageProps.format)`.
67 `contextHandle` is assumed to be previously initialized dwContextHandle_t.
70 dwPyramid_create(&pyramidPrevious, levelCount,
71 inputImageProps.width, inputImageProps.height, pxlType, context);
73 dwPyramid_create(&pyramidCurrent, levelCount,
74 inputImageProps.width, inputImageProps.height, pxlType,context);
77 #### Add bounding boxes to be tracked to the tracker. BBox can be extracted from the DNN detector, or defined by the user.
80 // get bbox from DNN detector or user defining
81 uint32_t nNewBoxes = ...;
82 dwBox2Df* newBoxes = ...;
84 *featureData.featureCount = nNewBoxes;
85 for (uint32_t i = 0; i < nNewBoxes; i++) {
86 featureData.locations[i] = {newBoxes[i].x + newBoxes[i].width/2, newBoxes[i].y + newBoxes[i].height/2};
87 featureData.sizes[i] = {newBoxes[i].width, newBoxes[i].height}
88 featureData.statuses[i] = DW_FEATURE_STATUS_DETECTED;
92 dwTemplateArray_copy(&templateGPU, &templateCPU, 0);
95 #### Start tracking the loop
100 // swap current/previous pyramid
101 // so new frame will always be built in pyramidCurrent
102 // and old pyramid will be stored in pyramidPrevious
103 std::swap(pyramidCurrent, pyramidPrevious);
105 // CODE: Read image frame code
106 dwImageHandle_t image = ...;
108 // compute pyramid based on the new read frame image
109 dwImageFilter_computePyramid(&pyramidCurrent, image, 0, contextHandle);
111 dwTemplateTracker_trackPyramid(&templateGPU, &pyramidCurrent,
112 &pyramidPrevious, tracker);
114 // copy detected results to CPU
115 dwTemplateArray_copy(&templateCPU, &templateGPU, 0);
117 // break the loop when all features are killed
118 if (*featureData.featureCount == 0)
121 // do some stuff in CPU
122 featureData.locations[...];
123 featureData.sizes[...];
127 #### Finally, free previously allocated memory.
130 dwPyramid_destroy(pyramidPrevious);
131 dwPyramid_destroy(pyramidCurrent);
133 dwTemplateArray_destroy(templateCPU);
134 dwTemplateArray_destroy(templateGPU);
135 dwTemplateTracker_release(&tracker);
138 For the full implementation, refer to @ref dwx_template_tracker_sample.