29 #include <opencv2/core/version.hpp> 
   30 #include <opencv2/imgcodecs.hpp> 
   31 #include <opencv2/imgproc/imgproc.hpp> 
   32 #include <opencv2/videoio.hpp> 
   48 #define CHECK_STATUS(STMT)                                    \ 
   51         VPIStatus status = (STMT);                            \ 
   52         if (status != VPI_SUCCESS)                            \ 
   54             char buffer[VPI_MAX_STATUS_MESSAGE_LENGTH];       \ 
   55             vpiGetLastStatusMessage(buffer, sizeof(buffer));  \ 
   56             std::ostringstream ss;                            \ 
   57             ss << "line " << __LINE__ << ": ";                \
 
   58             ss << vpiStatusGetName(status) << ": " << buffer; \
 
   59             throw std::runtime_error(ss.str());               \
 
   63 static void ProcessMotionVector(
VPIImage mvImg, cv::Mat &outputImage)
 
   74     cv::Mat flow(mvImage.size(), CV_32FC2);
 
   75     mvImage.convertTo(flow, CV_32F, 1.0f / (1 << 5));
 
   83     cv::Mat magnitude, angle;
 
   85         cv::Mat flowChannels[2];
 
   86         split(flow, flowChannels);
 
   87         cv::cartToPolar(flowChannels[0], flowChannels[1], magnitude, angle, 
true);
 
   91     cv::threshold(magnitude, magnitude, clip, clip, cv::THRESH_TRUNC);
 
   94     cv::Mat _hsv[3], hsv, bgr;
 
   96     _hsv[1] = cv::Mat::ones(angle.size(), CV_32F);
 
   97     _hsv[2] = magnitude / clip; 
 
  100     cv::cvtColor(hsv, bgr, cv::COLOR_HSV2BGR);
 
  101     bgr.convertTo(outputImage, CV_8U, 255.0);
 
  104 int main(
int argc, 
char *argv[])
 
  108     cv::Mat cvPrevFrame, cvCurFrame;
 
  131             throw std::runtime_error(std::string(
"Usage: ") + argv[0] +
 
  132                                      " <ofa> <input_video> <low|medium|high> <gridsize> <numlevels>");
 
  136         std::string strBackend    = argv[1];
 
  137         std::string strInputVideo = argv[2];
 
  138         std::string strQuality    = argv[3];
 
  139         std::string strGridSize   = argv[4];
 
  140         std::string strNumLevels  = argv[5];
 
  143         if (strQuality == 
"low")
 
  147         else if (strQuality == 
"medium")
 
  151         else if (strQuality == 
"high")
 
  157             throw std::runtime_error(
"Unknown quality provided");
 
  161         if (strBackend == 
"ofa")
 
  167             throw std::runtime_error(
"Backend '" + strBackend + 
"' not recognized, it must be ofa.");
 
  171         int gridSize = strtol(strGridSize.c_str(), &endptr, 10);
 
  174             throw std::runtime_error(
"Syntax error parsing gridsize " + strGridSize);
 
  177         int numLevels = strtol(strNumLevels.c_str(), &endptr, 10);
 
  180             throw std::runtime_error(
"Syntax error parsing numlevels " + strNumLevels);
 
  184         cv::VideoCapture invid;
 
  185         if (!invid.open(strInputVideo))
 
  187             throw std::runtime_error(
"Can't open '" + strInputVideo + 
"'");
 
  195         if (!invid.read(cvPrevFrame))
 
  197             throw std::runtime_error(
"Cannot read frame from input video");
 
  209         int32_t width  = cvPrevFrame.cols;
 
  210         int32_t height = cvPrevFrame.rows;
 
  213         std::vector<int32_t> pyrGridSize(numLevels, gridSize); 
 
  222         CHECK_STATUS(
vpiImageCreate(width, height, imgFmt, 0, &imgPrevFrameTmp));
 
  223         CHECK_STATUS(
vpiImageCreate(width, height, imgFmt, 0, &imgCurFrameTmp));
 
  228         CHECK_STATUS(
vpiPyramidCreate(width, height, imgFmt, pyrGridSize.size(), 0.5, 0, &prevPyrTmp));
 
  229         CHECK_STATUS(
vpiPyramidCreate(width, height, imgFmt, pyrGridSize.size(), 0.5, 0, &curPyrTmp));
 
  231         CHECK_STATUS(
vpiPyramidCreate(width, height, imgFmtBL, pyrGridSize.size(), 0.5, 0, &prevPyrBL));
 
  232         CHECK_STATUS(
vpiPyramidCreate(width, height, imgFmtBL, pyrGridSize.size(), 0.5, 0, &curPyrBL));
 
  235         int32_t mvWidth  = (width + gridSize - 1) / gridSize;
 
  236         int32_t mvHeight = (height + gridSize - 1) / gridSize;
 
  239         int fourcc = cv::VideoWriter::fourcc(
'M', 
'P', 
'E', 
'G');
 
  240         double fps = invid.get(cv::CAP_PROP_FPS);
 
  242         cv::VideoWriter outVideo(
"denseoptflow_mv_" + strBackend + 
".mp4", fourcc, fps, cv::Size(mvWidth, mvHeight));
 
  243         if (!outVideo.isOpened())
 
  245             throw std::runtime_error(
"Can't create output video");
 
  258         cv::Mat mvOutputImage;
 
  262         while (invid.read(cvCurFrame))
 
  264             printf(
"Processing frame %d\n", idxFrame++);
 
  281             ProcessMotionVector(imgMotionVecBL, mvOutputImage);
 
  284             outVideo << mvOutputImage;
 
  287             std::swap(cvPrevFrame, cvCurFrame);
 
  288             std::swap(imgPrevFramePL, imgCurFramePL);
 
  289             std::swap(prevPyrBL, curPyrBL);
 
  292     catch (std::exception &e)
 
  294         std::cerr << e.what() << std::endl;
 
Functions and structures for dealing with VPI arrays.
 
Declares functions that handle gaussian pyramids.
 
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 vpiSubmitGaussianPyramidGenerator(VPIStream stream, uint64_t backend, VPIImage input, VPIPyramid output, VPIBorderExtension border)
Computes the Gaussian pyramid from the input image.
 
void vpiImageDestroy(VPIImage img)
Destroy an image instance.
 
struct VPIImageImpl * VPIImage
A handle to an image.
 
VPIStatus vpiImageLockData(VPIImage img, VPILockMode mode, VPIImageBufferType bufType, VPIImageData *data)
Acquires the lock on an image object and returns the image contents.
 
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 vpiImageUnlock(VPIImage img)
Releases the lock on an image object.
 
@ VPI_IMAGE_BUFFER_HOST_PITCH_LINEAR
Host-accessible with planes in pitch-linear memory layout.
 
Stores information about image characteristics and content.
 
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 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 vpiCreateOpticalFlowDense(uint64_t backends, int32_t width, int32_t height, VPIImageFormat inputFmt, const int32_t *gridSize, int32_t numLevels, VPIOpticalFlowQuality quality, VPIPayload *payload)
Creates payload for vpiSubmitOpticalFlowDense.
 
VPIStatus vpiSubmitOpticalFlowDensePyramid(VPIStream stream, uint64_t backend, VPIPayload payload, VPIPyramid prevPyr, VPIPyramid curPyr, VPIImage mvImg)
Runs dense Optical Flow on two frames, outputting motion vectors.
 
struct VPIPayloadImpl * VPIPayload
A handle to an algorithm payload.
 
void vpiPayloadDestroy(VPIPayload payload)
Deallocates the payload object and all associated resources.
 
VPIStatus vpiPyramidCreate(int32_t width, int32_t height, VPIImageFormat fmt, int32_t numLevels, float scale, uint64_t flags, VPIPyramid *pyr)
Create an empty image pyramid instance with the specified flags.
 
struct VPIPyramidImpl * VPIPyramid
A handle to an image pyramid.
 
void vpiPyramidDestroy(VPIPyramid pyr)
Destroy an image pyramid instance as well as all resources it owns.
 
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_OFA
OFA backend.
 
@ VPI_BACKEND_VIC
VIC backend.
 
VPIOpticalFlowQuality
Defines the quality of the optical flow algorithm.
 
@ VPI_BORDER_CLAMP
Border pixels are repeated indefinitely.
 
@ 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.