29 #include <opencv2/core.hpp>
30 #include <opencv2/features2d.hpp>
31 #include <opencv2/imgcodecs.hpp>
32 #include <opencv2/imgproc.hpp>
33 #include <opencv2/videoio.hpp>
57 #define CHECK_STATUS(STMT) \
60 VPIStatus status = (STMT); \
61 if (status != VPI_SUCCESS) \
63 char buffer[VPI_MAX_STATUS_MESSAGE_LENGTH]; \
64 vpiGetLastStatusMessage(buffer, sizeof(buffer)); \
65 std::ostringstream ss; \
66 ss << vpiStatusGetName(status) << ": " << buffer; \
67 throw std::runtime_error(ss.str()); \
82 using TargetTrackInfoMap = std::map<int, TrackInfo>;
85 struct DetectedTargetInfo
91 bool lostTrack()
const
98 using DetectedTargetInfoMap = std::multimap<int, DetectedTargetInfo>;
100 VPIBackend ParseBackend(
const std::string &str)
106 else if (str ==
"pva")
112 throw std::runtime_error(
"Backend '" + str +
"' not recognized, it must be either cuda or pva.");
117 cv::VideoCapture ParseVideo(
const std::string &fname)
119 cv::VideoCapture video;
120 if (!video.open(fname))
122 throw std::runtime_error(
"Can't open '" + fname +
"'");
128 DetectedTargetInfoMap ParseTargetInfoAtFrame(
const std::string &fname)
130 std::ifstream in(fname);
133 throw std::runtime_error(
"Can't open '" + fname +
"'");
136 DetectedTargetInfoMap out;
140 DetectedTargetInfo tinfo;
141 while (in >> tinfo.idTarget >> frame >> tinfo.bbox.left >> tinfo.bbox.top >> tinfo.bbox.width >> tinfo.bbox.height)
143 out.emplace(frame, tinfo);
150 cv::Scalar GetRandomColor(cv::RNG &rng)
152 std::vector<cv::Vec3b> color = {cv::Vec3b{(
unsigned char)rng.uniform(0, 180), 255, 255}};
153 cvtColor(color, color, cv::COLOR_HSV2BGR);
154 return cv::Scalar(color[0][0], color[0][1], color[0][2], 255);
158 bool AddNewTargetsFromFrame(
int idxFrame, DetectedTargetInfoMap &tgtInfos, TargetTrackInfoMap &trackInfo,
166 const auto *tgtBegin = pTarget;
168 static cv::RNG rng(1);
171 auto tgtInfoRange = tgtInfos.equal_range(idxFrame);
172 for (
auto it = tgtInfoRange.first; it != tgtInfoRange.second; ++it)
175 if (it->second.lostTrack())
182 auto itTrackInfo = trackInfo.find(it->second.idTarget);
183 if (itTrackInfo != trackInfo.end() && itTrackInfo->second.enabled)
201 pTarget->bbox = it->second.bbox;
203 pTarget->seqIndex = 0;
205 pTarget->filterLR = 0.075;
206 pTarget->filterChannelWeightsLR = 0.1;
209 if (itTrackInfo == trackInfo.end())
213 tinfo.idTarget = it->second.idTarget;
214 tinfo.color = GetRandomColor(rng);
215 tinfo.enabled =
true;
216 itTrackInfo = trackInfo.emplace(tinfo.idTarget, tinfo).first;
221 itTrackInfo->second.enabled =
true;
224 pTarget->userData = &itTrackInfo->second;
238 bool DetectTrackingLost(
int idxFrame, DetectedTargetInfoMap &tgtInfos,
VPIArrayData &targets, cv::Size frameSize)
240 auto tgtInfoRange = tgtInfos.equal_range(idxFrame);
245 bool atLeastOneLost =
false;
250 pTarget >= pBeginTarget; --pTarget)
252 bool trackingLost =
false;
256 pTarget->bbox.left + pTarget->bbox.width > frameSize.width ||
257 pTarget->bbox.top + pTarget->bbox.height > frameSize.height))
265 for (
auto itInfo = tgtInfoRange.first; itInfo != tgtInfoRange.second; ++itInfo)
269 static_cast<const TrackInfo *
>(pTarget->userData)->idTarget == itInfo->second.idTarget &&
270 itInfo->second.lostTrack())
281 atLeastOneLost =
true;
285 static_cast<TrackInfo *
>(pTarget->userData)->enabled =
false;
298 return atLeastOneLost;
302 bool RefineTracksAtFrame(
int idxFrame, DetectedTargetInfoMap &tgtInfos,
VPIArrayData &targets)
304 auto tgtInfoRange = tgtInfos.equal_range(idxFrame);
306 bool atLeastOneUpdated =
false;
321 for (
auto itInfo = tgtInfoRange.first; itInfo != tgtInfoRange.second; ++itInfo)
324 if (itInfo->second.lostTrack())
331 static_cast<const TrackInfo *
>(pTarget->userData)->idTarget == itInfo->second.idTarget)
333 pTarget->bbox = itInfo->second.bbox;
341 atLeastOneUpdated =
true;
350 return atLeastOneUpdated;
353 void DrawTargets(cv::Mat &frame,
VPIArray targets)
361 for (
int o = 0; o < numObjs; ++o, ++ptgt)
369 auto &tinfo = *
static_cast<TrackInfo *
>(ptgt->userData);
372 cv::Rect{(int)ptgt->bbox.left, (
int)ptgt->bbox.top, (int)ptgt->bbox.width, (
int)ptgt->bbox.height},
379 void WriteToDisk(
const cv::Mat &img, std::string name,
int idx)
382 snprintf(buf,
sizeof(buf) - 1,
"%s_%03d.jpg", name.c_str(), idx);
383 buf[
sizeof(buf) - 1] =
'\0';
405 int main(
int argc,
char *argv[])
410 VPIArray inTargets = NULL, outTargets = NULL;
422 throw std::runtime_error(std::string(
"Usage: ") + argv[0] +
" <pva|cuda> <input_video> <bbox descr>");
426 cv::VideoCapture invid = ParseVideo(argv[2]);
427 DetectedTargetInfoMap targetInfoAtFrame = ParseTargetInfoAtFrame(argv[3]);
429 TargetTrackInfoMap trackInfo;
434 const int maxTrackedTargets = targetInfoAtFrame.size();
439 maxTrackedTargets, &cropScale));
448 maxTrackedTargets, &dcfInitParams, &dcf));
471 CHECK_STATUS(
vpiImageCreate(tgtPatchSize, tgtPatchSize * maxTrackedTargets, tgtPatchFormat, 0, &tgtPatches));
477 CHECK_STATUS(
vpiImageCreate(invid.get(cv::CAP_PROP_FRAME_WIDTH), invid.get(cv::CAP_PROP_FRAME_HEIGHT),
490 AddNewTargetsFromFrame(curFrame, targetInfoAtFrame, trackInfo, tgtData);
501 while (invid.read(cvFrame))
503 printf(
"Frame %d\n", curFrame);
506 PreprocessFrame(stream, cvFrame, wrappedOCVFrame, frame);
511 tgtPatchSize, tgtPatches));
525 tgtPatches, inTargets, outTargets,
529 targets = outTargets;
546 bool mustUpdateTargetPatches =
false;
571 DetectTrackingLost(curFrame, targetInfoAtFrame, tgtData, cv::Size{cvFrame.cols, cvFrame.rows});
574 mustUpdateTargetPatches |= RefineTracksAtFrame(curFrame, targetInfoAtFrame, tgtData);
577 mustUpdateTargetPatches |= AddNewTargetsFromFrame(curFrame, targetInfoAtFrame, trackInfo, tgtData);
586 if (mustUpdateTargetPatches)
590 tgtPatchSize, tgtPatches));
605 DrawTargets(cvFrame, targets);
606 WriteToDisk(cvFrame,
"frame", curFrame);
611 std::swap(inTargets, targets);
615 catch (std::exception &e)
617 std::cerr << e.what() << std::endl;
Functions and structures for dealing with VPI arrays.
Declares functions that implement the Crop Scaler algorithm.
Declares functions that implement the DCF Tracker algorithm.
Functions and structures for dealing with VPI images.
Functions for handling OpenCV interoperability with VPI.
Functions and structures for dealing with VPI pyramids.
Declaration of VPI status codes handling functions.
Declares functions dealing with VPI streams.
@ VPI_TRACKING_STATE_LOST
Object isn't being tracked anymore.
@ VPI_TRACKING_STATE_SHADOW_TRACKED
Object is being tracked with low confidence.
@ VPI_TRACKING_STATE_TRACKED
Object is being tracked with high confidence.
@ VPI_TRACKING_STATE_NEW
New object to be tracked.
void * data
Points to the first element of the array.
VPIArrayBuffer buffer
Stores the array contents.
int32_t * sizePointer
Points to the number of elements in the array.
VPIArrayBufferAOS aos
Array stored in array-of-structures layout.
int32_t capacity
Maximum number of elements that the array can hold.
VPIStatus vpiArrayUnlock(VPIArray array)
Releases the lock on array object.
VPIStatus vpiArrayLockData(VPIArray array, VPILockMode mode, VPIArrayBufferType bufType, VPIArrayData *data)
Acquires the lock on an array object and returns the array contents.
void vpiArrayDestroy(VPIArray array)
Destroy an array instance.
VPIStatus vpiArrayCreate(int32_t capacity, VPIArrayType type, uint64_t flags, VPIArray *array)
Create an empty array instance.
struct VPIArrayImpl * VPIArray
A handle to an array.
@ VPI_ARRAY_TYPE_DCF_TRACKED_BOUNDING_BOX
VPIDCFTrackedBoundingBox element.
@ VPI_ARRAY_BUFFER_HOST_AOS
Host-accessible array-of-structures.
Stores information about array characteristics and contents.
VPIStatus vpiCreateCropScaler(uint64_t backends, int maxFrames, int maxObjects, VPIPayload *payload)
Creates payload instance for the Crop Scale algorithm.
VPIStatus vpiSubmitCropScalerBatch(VPIStream stream, uint64_t backend, VPIPayload payload, VPIImage *frameList, int32_t numFrames, VPIArray objects, int32_t patchWidth, int32_t patchHeight, VPIImage outPatches)
Crops rectangular regions from the input frames and rescale them all to the same dimensions.
int32_t hogCellSize
Cell size for features from Histogram of Oriented Gradients.
int32_t featurePatchSize
Size of an object feature patch.
VPIStatus vpiSubmitDCFTrackerLocalizeBatch(VPIStream stream, uint64_t backend, VPIPayload payload, const int32_t *enabledSequences, int32_t numSequences, VPIImage featureMaskingWindow, VPIImage inPatches, VPIArray inObjects, VPIArray outObjects, VPIImage outCorrelationResponses, VPIArray outMaxCorrelationResponses, const VPIDCFTrackerParams *params)
Localizes each tracked object in the input image patches using the Discriminative Correlation Filter ...
VPIStatus vpiSubmitDCFTrackerUpdateBatch(VPIStream stream, uint64_t backend, VPIPayload payload, const int32_t *enabledSequences, int32_t numSequences, VPIImage featureMaskingWindow, VPIImage modelMaskingWindow, VPIImage inPatches, VPIArray trackedObjects, const VPIDCFTrackerParams *params)
Update internal object tracking information based on its state and its corresponding input image patc...
VPIStatus vpiCreateDCFTracker(uint64_t backends, int32_t maxNumSequences, int32_t maxNumObjects, const VPIDCFTrackerCreationParams *params, VPIPayload *payload)
Creates payload for DCF Tracker.
VPIStatus vpiInitDCFTrackerCreationParams(VPIDCFTrackerCreationParams *params)
Initialize VPIDCFTrackerCreationParams with default values.
Stores information about an object tracked by DCF Tracker.
Creation parameters of DCF Tracker.
void vpiImageDestroy(VPIImage img)
Destroy an image instance.
struct VPIImageImpl * VPIImage
A handle to an image.
VPIStatus vpiImageCreate(int32_t width, int32_t height, VPIImageFormat fmt, uint64_t flags, VPIImage *img)
Create an empty image instance with the specified flags.
VPIStatus vpiImageCreateWrapperOpenCVMat(const cv::Mat &mat, VPIImageFormat fmt, uint64_t flags, VPIImage *img)
Wraps a cv::Mat in an VPIImage with the given image format.
VPIStatus vpiImageSetWrappedOpenCVMat(VPIImage img, const cv::Mat &mat)
Redefines the wrapped cv::Mat of an existing VPIImage wrapper.
struct VPIPayloadImpl * VPIPayload
A handle to an algorithm payload.
void vpiPayloadDestroy(VPIPayload payload)
Deallocates the payload object and all associated resources.
struct VPIStreamImpl * VPIStream
A handle to a stream.
VPIStatus vpiStreamSync(VPIStream stream)
Blocks the calling thread until all submitted commands in this stream queue are done (queue is empty)...
VPIBackend
VPI Backend types.
void vpiStreamDestroy(VPIStream stream)
Destroy a stream instance and deallocate all HW resources.
VPIStatus vpiStreamCreate(uint64_t flags, VPIStream *stream)
Create a stream instance.
@ VPI_BACKEND_CUDA
CUDA backend.
@ VPI_BACKEND_PVA
PVA backend.
float height
Bounding box height.
float width
Bounding box width.
@ VPI_LOCK_READ_WRITE
Lock memory for reading and writing.
@ VPI_LOCK_READ
Lock memory only for reading.
Stores an axis-aligned 32-bit floating point 2D bounding box.