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>
52 #define CHECK_STATUS(STMT) \
55 VPIStatus status = (STMT); \
56 if (status != VPI_SUCCESS) \
58 char buffer[VPI_MAX_STATUS_MESSAGE_LENGTH]; \
59 vpiGetLastStatusMessage(buffer, sizeof(buffer)); \
60 std::ostringstream ss; \
61 ss << vpiStatusGetName(status) << ": " << buffer; \
62 throw std::runtime_error(ss.str()); \
66 static void ProcessMotionVector(
VPIImage mvImg, cv::Mat &outputImage)
77 cv::Mat flow(mvImage.size(), CV_32FC2);
78 mvImage.convertTo(flow, CV_32F, 1.0f / (1 << 5));
86 cv::Mat magnitude, angle;
88 cv::Mat flowChannels[2];
89 split(flow, flowChannels);
90 cv::cartToPolar(flowChannels[0], flowChannels[1], magnitude, angle,
true);
94 cv::threshold(magnitude, magnitude, clip, clip, cv::THRESH_TRUNC);
97 cv::Mat _hsv[3], hsv, bgr;
99 _hsv[1] = cv::Mat::ones(angle.size(), CV_32F);
100 _hsv[2] = magnitude / clip;
103 cv::cvtColor(hsv, bgr, cv::COLOR_HSV2BGR);
104 bgr.convertTo(outputImage, CV_8U, 255.0);
107 int main(
int argc,
char *argv[])
111 cv::Mat cvPrevFrame, cvCurFrame;
130 throw std::runtime_error(std::string(
"Usage: ") + argv[0] +
" <nvenc> <input_video> <low|medium|high>");
134 std::string strBackend = argv[1];
135 std::string strInputVideo = argv[2];
136 std::string strQuality = argv[3];
139 if (strQuality ==
"low")
143 else if (strQuality ==
"medium")
147 else if (strQuality ==
"high")
153 throw std::runtime_error(
"Unknown quality provided");
157 if (strBackend ==
"nvenc")
163 throw std::runtime_error(
"Backend '" + strBackend +
"' not recognized, it must be nvenc.");
167 cv::VideoCapture invid;
168 if (!invid.open(strInputVideo))
170 throw std::runtime_error(
"Can't open '" + strInputVideo +
"'");
178 if (!invid.read(cvPrevFrame))
180 throw std::runtime_error(
"Cannot read frame from input video");
192 int32_t width = cvPrevFrame.cols;
193 int32_t height = cvPrevFrame.rows;
203 CHECK_STATUS(
vpiImageCreate(width, height, imgFmt, 0, &imgPrevFrameTmp));
204 CHECK_STATUS(
vpiImageCreate(width, height, imgFmt, 0, &imgCurFrameTmp));
208 CHECK_STATUS(
vpiImageCreate(width, height, imgFmtBL, 0, &imgPrevFrameBL));
209 CHECK_STATUS(
vpiImageCreate(width, height, imgFmtBL, 0, &imgCurFrameBL));
212 int32_t mvWidth = (width + 3) / 4;
213 int32_t mvHeight = (height + 3) / 4;
216 #if CV_MAJOR_VERSION >= 3
217 int fourcc = cv::VideoWriter::fourcc(
'a',
'v',
'c',
'1');
218 double fps = invid.get(cv::CAP_PROP_FPS);
219 std::string extOutputVideo =
".mp4";
223 int fourcc = CV_FOURCC(
'M',
'P',
'E',
'G');
224 double fps = invid.get(CV_CAP_PROP_FPS);
225 std::string extOutputVideo =
".avi";
228 cv::VideoWriter outVideo(
"denseoptflow_mv_" + strBackend + extOutputVideo, fourcc, fps,
229 cv::Size(mvWidth, mvHeight));
230 if (!outVideo.isOpened())
232 throw std::runtime_error(
"Can't create output video");
243 cv::Mat mvOutputImage;
247 while (invid.read(cvCurFrame))
249 printf(
"Processing frame %d\n", idxFrame++);
264 ProcessMotionVector(imgMotionVecBL, mvOutputImage);
267 outVideo << mvOutputImage;
270 std::swap(cvPrevFrame, cvCurFrame);
271 std::swap(imgPrevFramePL, imgCurFramePL);
272 std::swap(imgPrevFrameBL, imgCurFrameBL);
275 catch (std::exception &e)
277 std::cerr << e.what() << std::endl;
Functions and structures for dealing with VPI arrays.
Functions and structures for dealing with VPI images.
Functions for handling OpenCV interoperability with VPI.
Declares functions that implement the dense optical flow.
Functions and structures for dealing with VPI pyramids.
Declaration of VPI status codes handling functions.
Declares functions dealing with VPI streams.
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 vpiImageCreate(int32_t width, int32_t height, VPIImageFormat fmt, uint32_t flags, VPIImage *img)
Create an empty image instance with the specified flags.
VPIStatus vpiImageUnlock(VPIImage img)
Releases the lock on an image object.
Stores information about image characteristics and content.
VPIStatus vpiImageDataExportOpenCVMat(const VPIImageData &imgData, cv::Mat *mat)
Fills an existing cv::Mat with data from VPIImageData coming from a locked VPIImage.
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.
VPIStatus vpiSubmitOpticalFlowDense(VPIStream stream, uint32_t backend, VPIPayload payload, VPIImage prevImg, VPIImage curImg, VPIImage mvImg)
Runs dense Optical Flow on two frames.
VPIStatus vpiCreateOpticalFlowDense(uint32_t backends, int32_t width, int32_t height, VPIImageFormat inputFmt, VPIOpticalFlowQuality quality, VPIPayload *payload)
Creates payload for vpiSubmitOpticalFlowDense.
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_NVENC
NVENC backend.
@ VPI_BACKEND_VIC
VIC backend.
VPIOpticalFlowQuality
Defines the quality of the optical flow algorithm.
@ VPI_OPTICAL_FLOW_QUALITY_LOW
Fast but low quality optical flow implementation.
@ VPI_OPTICAL_FLOW_QUALITY_HIGH
Slow but high quality optical flow implementation.
@ VPI_OPTICAL_FLOW_QUALITY_MEDIUM
Speed and quality in between of VPI_OPTICAL_FLOW_QUALITY_LOW and VPI_OPTICAL_FLOW_QUALITY_HIGH.
@ VPI_LOCK_READ
Lock memory only for reading.