29 #include <opencv2/core/version.hpp>
30 #if CV_MAJOR_VERSION >= 3
31 # include <opencv2/imgcodecs.hpp>
32 # include <opencv2/videoio.hpp>
34 # include <opencv2/highgui/highgui.hpp>
37 #include <opencv2/imgproc/imgproc.hpp>
53 #define CHECK_STATUS(STMT) \
56 VPIStatus status = (STMT); \
57 if (status != VPI_SUCCESS) \
59 char buffer[VPI_MAX_STATUS_MESSAGE_LENGTH]; \
60 vpiGetLastStatusMessage(buffer, sizeof(buffer)); \
61 std::ostringstream ss; \
62 ss << vpiStatusGetName(status) << ": " << buffer; \
63 throw std::runtime_error(ss.str()); \
96 throw std::runtime_error(
"Image type not supported");
102 if (cvimg.type() == CV_16U)
104 cvimg.convertTo(out, CV_8U);
109 cvtColor(cvimg, out, cv::COLOR_GRAY2BGR);
125 static std::vector<cv::Vec3b> colors;
131 for (
size_t i = 0; i < colors.size(); ++i)
133 colors[i] = cv::Vec3b(rand.uniform(0, 180), 255, 255);
135 cvtColor(colors, colors, cv::COLOR_HSV2BGR);
141 if (pboxes[i].trackingStatus == 1)
147 x = pboxes[i].bbox.xform.mat3[0][2] + ppreds[i].mat3[0][2];
148 y = pboxes[i].bbox.xform.mat3[1][2] + ppreds[i].mat3[1][2];
149 w = pboxes[i].bbox.width * pboxes[i].bbox.xform.mat3[0][0] * ppreds[i].mat3[0][0];
150 h = pboxes[i].bbox.height * pboxes[i].bbox.xform.mat3[1][1] * ppreds[i].mat3[1][1];
152 rectangle(out, cv::Rect(x, y, w, h), cv::Scalar(colors[i][0], colors[i][1], colors[i][2]), 2);
161 int main(
int argc,
char *argv[])
165 cv::Mat cvTemplate, cvReference;
168 VPIArray inputBoxList = NULL, inputPredList = NULL;
183 throw std::runtime_error(std::string(
"Usage: ") + argv[0] +
" <cpu|pva|cuda> <input_video> <bbox descr>");
186 std::string strBackend = argv[1];
187 std::string strInputVideo = argv[2];
188 std::string strInputBBoxes = argv[3];
191 cv::VideoCapture invid;
192 if (!invid.open(strInputVideo))
194 throw std::runtime_error(
"Can't open '" + strInputVideo +
"'");
198 #if CV_MAJOR_VERSION >= 3
199 int w = invid.get(cv::CAP_PROP_FRAME_WIDTH);
200 int h = invid.get(cv::CAP_PROP_FRAME_HEIGHT);
201 int fourcc = cv::VideoWriter::fourcc(
'a',
'v',
'c',
'1');
202 double fps = invid.get(cv::CAP_PROP_FPS);
203 std::string extOutputVideo =
".mp4";
207 int w = invid.get(CV_CAP_PROP_FRAME_WIDTH);
208 int h = invid.get(CV_CAP_PROP_FRAME_HEIGHT);
209 int fourcc = CV_FOURCC(
'M',
'P',
'E',
'G');
210 double fps = invid.get(CV_CAP_PROP_FPS);
211 std::string extOutputVideo =
".avi";
214 cv::VideoWriter outVideo(
"klt_" + strBackend + extOutputVideo, fourcc, fps, cv::Size(w, h));
215 if (!outVideo.isOpened())
217 throw std::runtime_error(
"Can't create output video");
225 std::vector<VPIKLTTrackedBoundingBox> bboxes;
226 int32_t bboxesSize = 0;
227 std::vector<VPIHomographyTransform2D> preds;
228 int32_t predsSize = 0;
232 std::map<int, size_t> bboxes_size_at_frame;
240 std::ifstream in(strInputBBoxes);
243 throw std::runtime_error(
"Can't open '" + strInputBBoxes +
"'");
247 int frame, x, y, w, h;
248 while (in >> frame >> x >> y >> w >> h)
250 if (bboxes.size() == 64)
252 throw std::runtime_error(
"Too many bounding boxes");
273 bboxes.push_back(track);
277 xform.
mat3[0][0] = 1;
278 xform.
mat3[1][1] = 1;
279 xform.
mat3[2][2] = 1;
280 preds.push_back(xform);
282 bboxes_size_at_frame[frame] = bboxes.size();
285 if (!in && !in.eof())
287 throw std::runtime_error(
"Can't parse bounding boxes, stopped at bbox #" +
288 std::to_string(bboxes.size()));
296 data.
data = &bboxes[0];
301 data.
data = &preds[0];
308 if (strBackend ==
"cpu")
312 else if (strBackend ==
"cuda")
316 else if (strBackend ==
"pva")
322 throw std::runtime_error(
"Backend '" + strBackend +
323 "' not recognized, it must be either cpu, cuda or pva.");
331 auto fetchFrame = [&invid, &nextFrame, backend]() {
333 if (!invid.read(frame))
339 if (frame.channels() == 3)
341 cvtColor(frame, frame, cv::COLOR_BGR2GRAY);
350 frame.convertTo(aux, CV_16U);
355 assert(frame.type() == CV_8U);
364 cvTemplate = fetchFrame();
388 size_t curNumBoxes = 0;
392 size_t curFrame = nextFrame - 1;
395 auto tmp = --bboxes_size_at_frame.upper_bound(curFrame);
396 size_t bbox_count = tmp->second;
398 assert(bbox_count >= curNumBoxes &&
"input bounding boxes must be sorted by frame");
401 if (curNumBoxes != bbox_count)
413 for (
size_t i = 0; i < bbox_count - curNumBoxes; ++i)
415 std::cout << curFrame <<
" -> new " << curNumBoxes + i << std::endl;
417 assert(bbox_count <= bboxes.capacity());
418 assert(bbox_count <= preds.capacity());
420 curNumBoxes = bbox_count;
424 outVideo << WriteKLTBoxes(imgTemplate, inputBoxList, inputPredList);
427 cvReference = fetchFrame();
430 if (cvReference.data == NULL)
442 imgReference, outputBoxList, outputEstimList, ¶ms));
458 for (
size_t b = 0; b < curNumBoxes; ++b)
461 if (updated_bbox[b].trackingStatus)
464 if (bboxes[b].trackingStatus == 0)
466 std::cout << curFrame <<
" -> dropped " << b << std::endl;
467 bboxes[b].trackingStatus = 1;
474 if (updated_bbox[b].templateStatus)
476 std::cout << curFrame <<
" -> update " << b << std::endl;
486 bboxes[b] = updated_bbox[b];
489 bboxes[b].templateStatus = 1;
493 preds[b].
mat3[0][0] = 1;
494 preds[b].mat3[1][1] = 1;
495 preds[b].mat3[2][2] = 1;
500 bboxes[b].templateStatus = 0;
517 std::swap(imgTemplate, imgReference);
518 std::swap(cvTemplate, cvReference);
521 catch (std::exception &e)
523 std::cerr << e.what() << std::endl;
Functions and structures for dealing with VPI arrays.
Functions and structures for dealing with VPI images.
Declares functions that implement the KLT Feature Tracker algorithm.
Functions for handling OpenCV interoperability with VPI.
Declaration of VPI status codes handling functions.
Declares functions dealing with VPI streams.
int32_t * sizePointer
Points to the number of elements in the array.
int32_t capacity
Maximum number of elements that the array can hold.
VPIArrayType type
Type of each array element.
void * data
Points to the first element of the array.
VPIStatus vpiArraySetSize(VPIArray array, int32_t size)
Set the array size in elements.
VPIStatus vpiArrayUnlock(VPIArray array)
Releases the lock on array object.
VPIStatus vpiArrayLock(VPIArray array, VPILockMode mode, VPIArrayData *arrayData)
Acquires the lock on array object and returns a pointer to array data.
void vpiArrayDestroy(VPIArray array)
Destroy an array instance.
VPIStatus vpiArrayCreate(int32_t capacity, VPIArrayType type, uint32_t flags, VPIArray *array)
Create an empty array instance.
struct VPIArrayImpl * VPIArray
A handle to an array.
VPIStatus vpiArrayInvalidate(VPIArray array)
Informs that the array's wrapped memory was updated outside VPI.
@ VPI_ARRAY_TYPE_KLT_TRACKED_BOUNDING_BOX
VPIKLTTrackedBoundingBox element.
@ VPI_ARRAY_TYPE_HOMOGRAPHY_TRANSFORM_2D
VPIHomographyTransform2D element.
Stores information about array characteristics and content.
VPIStatus vpiArrayCreateHostMemWrapper(const VPIArrayData *arrayData, uint32_t flags, VPIArray *array)
Create an array object by wrapping an existing host memory block.
int32_t height
Height of this plane in pixels.
int32_t width
Width of this plane in pixels.
void * data
Pointer to the first row of this plane.
int32_t pitchBytes
Difference in bytes of beginning of one row and the beginning of the previous.
VPIImagePlane planes[VPI_MAX_PLANE_COUNT]
Data of all image planes.
VPIImageFormat format
Image format.
VPIStatus vpiImageLock(VPIImage img, VPILockMode mode, VPIImageData *hostData)
Acquires the lock on an image object and returns a pointer to the image planes.
void vpiImageDestroy(VPIImage img)
Destroy an image instance.
struct VPIImageImpl * VPIImage
A handle to an image.
VPIStatus vpiImageGetFormat(VPIImage img, VPIImageFormat *format)
Get the image format.
VPIStatus vpiImageUnlock(VPIImage img)
Releases the lock on an image object.
Stores information about image characteristics and content.
int8_t templateStatus
Status of the template related to this bounding box.
int8_t trackingStatus
Tracking status of this bounding box.
VPIBoundingBox bbox
Bounding box being tracked.
VPIStatus vpiSubmitKLTFeatureTracker(VPIStream stream, uint32_t backend, VPIPayload payload, VPIImage templateImage, VPIArray inputBoxList, VPIArray inputPredictionList, VPIImage referenceImage, VPIArray outputBoxList, VPIArray outputEstimationList, const VPIKLTFeatureTrackerParams *params)
Runs KLT Feature Tracker on two frames.
VPIStatus vpiCreateKLTFeatureTracker(uint32_t backends, int32_t imageWidth, int32_t imageHeight, VPIImageFormat imageFormat, const VPIKLTFeatureTrackerCreationParams *params, VPIPayload *payload)
Creates payload for vpiSubmitKLTFeatureTracker.
VPIStatus vpiInitKLTFeatureTrackerParams(VPIKLTFeatureTrackerParams *params)
Initialize VPIKLTFeatureTrackerParams with default values.
Structure that defines the parameters for vpiCreateKLTFeatureTracker.
Stores a bounding box that is being tracked by KLT Tracker.
VPIStatus vpiImageSetWrappedOpenCVMat(VPIImage img, const cv::Mat &mat)
Redefines the wrapped cv::Mat of an existing VPIImage wrapper.
VPIStatus vpiImageCreateOpenCVMatWrapper(const cv::Mat &mat, VPIImageFormat fmt, uint32_t flags, VPIImage *img)
Wraps a cv::Mat in an VPIImage with the given image format.
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(uint32_t flags, VPIStream *stream)
Create a stream instance.
@ VPI_BACKEND_CUDA
CUDA backend.
@ VPI_BACKEND_PVA
PVA backend.
@ VPI_BACKEND_CPU
CPU backend.
float width
Bounding box width.
float height
Bounding box height.
VPIHomographyTransform2D xform
Defines the bounding box top left corner and its homography.
float mat3[3][3]
3x3 homogeneous matrix that defines the homography.
@ VPI_LOCK_READ_WRITE
Lock memory for reading and writing.
@ VPI_LOCK_READ
Lock memory only for reading.