The tutorial shows the general structure of a program that uses the 2D template tracker to track templates in a single camera.
Initialize template array on both CPU and GPU
contextHandle
is assumed to be previously initialized dwContextHandle_t
.
DW_FEATURE2D_MEMORY_TYPE_CPU, contextHandle);
DW_FEATURE2D_MEMORY_TYPE_CUDA, contextHandle);
Initialize template tracker parameters with default values
Modify parameters according to tracking requirements
imageProps
is the dwImageProperties
structure of image to be tracked
Select on which processor the tracker should be performed on. Allowed option is DW_PROCESSOR_TYPE_GPU
.
Initialize template tracker with given parameters and bind output
Create 2 image pyramids as detection/tracking input: one is current, one is previous, the 2 pyramids work as a double buffer (or ping-pong buffer). They swap each other after each detection/tracking cycle. So new frame will always be read into pyramidCurrent and the previous frame will be stored to pyramidPrevious.
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.
inputImageProps.width
, inputImageProps.height
are the same in tracker/detector initialization
imagePxlType
should be got from dwImage_getPixelType(inputImageProps.format)
.
contextHandle
is assumed to be previously initialized dwContextHandle_t.
inputImageProps.width, inputImageProps.height, pxlType, context);
inputImageProps.width, inputImageProps.height, pxlType,context);
Add bounding boxes to be tracked to the tracker. BBox can be extracted from the DNN detector, or defined by the user.
uint32_t nNewBoxes = ...;
*featureData.featureCount = nNewBoxes;
for (uint32_t i = 0; i < nNewBoxes; i++) {
featureData.locations[i] = {newBoxes[i].
x + newBoxes[i].
width/2, newBoxes[i].
y + newBoxes[i].
height/2};
featureData.sizes[i] = {newBoxes[i].
width, newBoxes[i].
height}
featureData.statuses[i] = DW_FEATURE_STATUS_DETECTED;
}
dwTemplateArray_copy(&templateGPU, &templateCPU, 0);
Start tracking the loop
while(true)
{
std::swap(pyramidCurrent, pyramidPrevious);
&pyramidPrevious, tracker);
dwTemplateArray_copy(&templateCPU, &templateGPU, 0);
if (*featureData.featureCount == 0)
break;
featureData.locations[...];
featureData.sizes[...];
}
Finally, free previously allocated memory.
For the full implementation, refer to Template Tracker Sample.