DriveWorks SDK Reference
3.0.4260 Release
For Test and Development only

imageprocessing/tracking/docs/usecase1.md
Go to the documentation of this file.
1 # Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
2 
3 @page imageprocessing_tracking_usecase1 Single Camera Template Tracking
4 
5 @note SW Release Applicability: This tutorial is applicable to modules in both **NVIDIA DriveWorks** and **NVIDIA DRIVE Software** releases.
6 
7 The tutorial shows the general structure of a program that uses the 2D template tracker to track templates in a single camera.
8 
9 #### Initialize template array on both CPU and GPU
10 
11 `contextHandle` is assumed to be previously initialized `::dwContextHandle_t`.
12 ```{.cpp}
13  dwTemplateArray_create(&templateCPU, maxFeatureCount,
14  DW_FEATURE2D_MEMORY_TYPE_CPU, contextHandle);
15  dwTemplateArray_create(&templateGPU, maxFeatureCount,
16  DW_FEATURE2D_MEMORY_TYPE_CUDA, contextHandle);
17 
18 ```
19 
20 #### Initialize template tracker parameters with default values
21 
22 ```{.cpp}
23  dwTemplateTrackerParameters params = {};
24  dwTemplateTracker_initDefaultParams(&params);
25 ```
26 
27 #### Modify parameters according to tracking requirements
28 
29 `imageProps` is the `dwImageProperties` structure of image to be tracked
30 
31 ```{.cpp}
32  dwImage_getPixelType(&params.pxlType, imageProps.format);
33  params.validWidth = DW_MAX_TEMPLATE2D_SIZE;
34  params.validHeight = DW_MAX_TEMPLATE2D_SIZE;
35 
36 ```
37 
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>&trade;</sup> platforms.
41 Moreover, if the processor is set to PVA, the image dimensions need to be provided at initialization.
42 
43 ```{.cpp}
44  params.processorType = DW_PROCESSOR_TYPE_PVA_0;
45  params.imageWidth = 1280;
46  params.imageHeight = 800;
47 ```
48 
49 #### Initialize template tracker with given parameters and bind output
50 
51 ```{.cpp}
52  dwTemplateTracker_initialize(&tracker, &params, 0, contextHandle);
53 ```
54 
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
59 pyramidPrevious.
60 
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.
62 
63 `inputImageProps.width`, `inputImageProps.height` are the same in tracker/detector initialization
64 
65 `imagePxlType` should be got from `dwImage_getPixelType(inputImageProps.format)`.
66 
67 `contextHandle` is assumed to be previously initialized dwContextHandle_t.
68 
69 ```{.cpp}
70  dwPyramid_create(&pyramidPrevious, levelCount,
71  inputImageProps.width, inputImageProps.height, pxlType, context);
72 
73  dwPyramid_create(&pyramidCurrent, levelCount,
74  inputImageProps.width, inputImageProps.height, pxlType,context);
75 ```
76 
77 #### Add bounding boxes to be tracked to the tracker. BBox can be extracted from the DNN detector, or defined by the user.
78 
79 ```{.cpp}
80  // get bbox from DNN detector or user defining
81  uint32_t nNewBoxes = ...;
82  dwBox2Df* newBoxes = ...;
83 
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;
89  }
90 
91  // copy data to GPU
92  dwTemplateArray_copy(&templateGPU, &templateCPU, 0);
93 ```
94 
95 #### Start tracking the loop
96 
97 ```{.cpp}
98  while(true)
99  {
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);
104 
105  // CODE: Read image frame code
106  dwImageHandle_t image = ...;
107 
108  // compute pyramid based on the new read frame image
109  dwImageFilter_computePyramid(&pyramidCurrent, image, 0, contextHandle);
110 
111  dwTemplateTracker_trackPyramid(&templateGPU, &pyramidCurrent,
112  &pyramidPrevious, tracker);
113 
114  // copy detected results to CPU
115  dwTemplateArray_copy(&templateCPU, &templateGPU, 0);
116 
117  // break the loop when all features are killed
118  if (*featureData.featureCount == 0)
119  break;
120 
121  // do some stuff in CPU
122  featureData.locations[...];
123  featureData.sizes[...];
124  }
125 ```
126 
127 #### Finally, free previously allocated memory.
128 
129 ```{.cpp}
130  dwPyramid_destroy(pyramidPrevious);
131  dwPyramid_destroy(pyramidCurrent);
132 
133  dwTemplateArray_destroy(templateCPU);
134  dwTemplateArray_destroy(templateGPU);
135  dwTemplateTracker_release(&tracker);
136 ```
137 
138 For the full implementation, refer to @ref dwx_template_tracker_sample.