Repository navigation
Expand file tree
/
Copy pathFarnebackOpticalFlow_GPU.cpp
More file actions
124 lines (97 loc) · 3.88 KB
/
Copy pathFarnebackOpticalFlow_GPU.cpp
File metadata and controls
124 lines (97 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//////////////////////////////////////////////////////////////////////////
// This example creates a C++ MEX-file for the GPU version of OpenCV's
// matchTemplate. Here matchTemplate uses normalized cross correlation method
// to search for matches between an image patch and an input image.
//
// This example requires the Parallel Computing Toolbox and a CUDA capable GPU.
//
// This example is only supported on Linux and Windows.
//
// Copyright 2014 The MathWorks, Inc.
//////////////////////////////////////////////////////////////////////////
// Include utilities for converting mxGPUArray to cv::gpu::GpuMat
#include "opencvgpumex.hpp"
#include "gpu/mxGPUArray.h"
///////////////////////////////////////////////////////////////////////////
// Return true if gpuArray data is UINT8
///////////////////////////////////////////////////////////////////////////
boolean_T isGPUDataUINT8(const mxArray * in)
{
// Get the underlying data type the gpuArray
const mxGPUArray * img = mxGPUCreateFromMxArray(in);
boolean_T isUINT8 = mxGPUGetClassID(img) == mxUINT8_CLASS;
// Clean up gpuArray header
mxGPUDestroyGPUArray(img);
return isUINT8;
}
///////////////////////////////////////////////////////////////////////////
// Check inputs
///////////////////////////////////////////////////////////////////////////
void checkInputs(int nrhs, const mxArray *prhs[])
{
const mwSize * tdims, * fdims;
// Check number of inputs
if (nrhs != 2)
{
mexErrMsgTxt("Incorrect number of inputs. Function expects 2 inputs.");
}
// Inputs must be gpuArrays
if (!mxIsGPUArray(prhs[0]) || !mxIsGPUArray(prhs[1]))
{
mexErrMsgTxt("Both input images must be stored in gpuArrays.");
}
const mxGPUArray * img1 = mxGPUCreateFromMxArray(prhs[0]);
const mxGPUArray * img2 = mxGPUCreateFromMxArray(prhs[1]);
// Check input dimensions
tdims = mxGPUGetDimensions(img1);
fdims = mxGPUGetDimensions(img2);
mwSize ndimsImg1 = mxGPUGetNumberOfDimensions(img1);
mwSize ndimsImg2 = mxGPUGetNumberOfDimensions(img2);
// Clean-up headers. Data is not deleted.
mxGPUDestroyGPUArray(img1);
mxGPUDestroyGPUArray(img2);
if (ndimsImg1 > 2)
{
mexErrMsgTxt("Incorrect number of dimensions. First input must be a matrix.");
}
if (ndimsImg2 > 2)
{
mexErrMsgTxt("Incorrect number of dimensions. Second input must be a matrix.");
}
if (tdims[0] > fdims[0])
{
mexErrMsgTxt("Template should be smaller than image.");
}
if (tdims[1] > fdims[1])
{
mexErrMsgTxt("Template should be smaller than image.");
}
if (!isGPUDataUINT8(prhs[0]) || !isGPUDataUINT8(prhs[1]))
{
mexErrMsgTxt("Input image must be a gpuArray with uint8 data.");
}
}
///////////////////////////////////////////////////////////////////////////
// Main entry point to a MEX function
///////////////////////////////////////////////////////////////////////////
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
// Ensure MATLAB's GPU support is available.
mxInitGPU();
// Check inputs to mex function
checkInputs(nrhs, prhs);
// Convert mxArray inputs into OpenCV types
cv::Ptr<cv::gpu::GpuMat> frame1 = ocvMxGpuArrayToGpuMat_uint8(prhs[0]);
cv::Ptr<cv::gpu::GpuMat> frame2 = ocvMxGpuArrayToGpuMat_uint8(prhs[1]);
// Allocate output matrix
int outRows = frame1->rows ;
int outCols = frame1->cols ;
cv::gpu::GpuMat flowx((int)outRows, (int)outCols, CV_32FC1);
cv::gpu::GpuMat flowy((int)outRows, (int)outCols, CV_32FC1);
cv::gpu::FarnebackOpticalFlow d_calc;
// Run the OpenCV template matching routine
d_calc(*frame1, *frame2, flowx, flowy);
// Put the data back into the output MATLAB gpuArray
plhs[0] = ocvMxGpuArrayFromGpuMat_single(flowx);
plhs[1] = ocvMxGpuArrayFromGpuMat_single(flowy);
}