Wrap SparseOptFlow class around PyrLK optical flow computation
This commit is contained in:
parent
9b70c44f00
commit
e22b838af8
@ -47,9 +47,9 @@ using namespace cv::cuda;
|
|||||||
|
|
||||||
#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER)
|
#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER)
|
||||||
|
|
||||||
Ptr<SparsePyrLKOpticalFlow> cv::cuda::SparsePyrLKOpticalFlow::create(Size, int, int, bool) { throw_no_cuda(); return Ptr<SparsePyrLKOpticalFlow>(); }
|
Ptr<cv::cuda::SparsePyrLKOpticalFlow> cv::cuda::SparsePyrLKOpticalFlow::create(Size, int, int, bool) { throw_no_cuda(); return Ptr<SparsePyrLKOpticalFlow>(); }
|
||||||
|
|
||||||
Ptr<DensePyrLKOpticalFlow> cv::cuda::DensePyrLKOpticalFlow::create(Size, int, int, bool) { throw_no_cuda(); return Ptr<DensePyrLKOpticalFlow>(); }
|
Ptr<cv::cuda::DensePyrLKOpticalFlow> cv::cuda::DensePyrLKOpticalFlow::create(Size, int, int, bool) { throw_no_cuda(); return Ptr<DensePyrLKOpticalFlow>(); }
|
||||||
|
|
||||||
#else /* !defined (HAVE_CUDA) */
|
#else /* !defined (HAVE_CUDA) */
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ namespace
|
|||||||
vPyr[idx].copyTo(v, stream);
|
vPyr[idx].copyTo(v, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SparsePyrLKOpticalFlowImpl : public SparsePyrLKOpticalFlow, private PyrLKOpticalFlowBase
|
class SparsePyrLKOpticalFlowImpl : public cv::cuda::SparsePyrLKOpticalFlow, private PyrLKOpticalFlowBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SparsePyrLKOpticalFlowImpl(Size winSize, int maxLevel, int iters, bool useInitialFlow) :
|
SparsePyrLKOpticalFlowImpl(Size winSize, int maxLevel, int iters, bool useInitialFlow) :
|
||||||
@ -366,12 +366,12 @@ namespace
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr<SparsePyrLKOpticalFlow> cv::cuda::SparsePyrLKOpticalFlow::create(Size winSize, int maxLevel, int iters, bool useInitialFlow)
|
Ptr<cv::cuda::SparsePyrLKOpticalFlow> cv::cuda::SparsePyrLKOpticalFlow::create(Size winSize, int maxLevel, int iters, bool useInitialFlow)
|
||||||
{
|
{
|
||||||
return makePtr<SparsePyrLKOpticalFlowImpl>(winSize, maxLevel, iters, useInitialFlow);
|
return makePtr<SparsePyrLKOpticalFlowImpl>(winSize, maxLevel, iters, useInitialFlow);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ptr<DensePyrLKOpticalFlow> cv::cuda::DensePyrLKOpticalFlow::create(Size winSize, int maxLevel, int iters, bool useInitialFlow)
|
Ptr<cv::cuda::DensePyrLKOpticalFlow> cv::cuda::DensePyrLKOpticalFlow::create(Size winSize, int maxLevel, int iters, bool useInitialFlow)
|
||||||
{
|
{
|
||||||
return makePtr<DensePyrLKOpticalFlowImpl>(winSize, maxLevel, iters, useInitialFlow);
|
return makePtr<DensePyrLKOpticalFlowImpl>(winSize, maxLevel, iters, useInitialFlow);
|
||||||
}
|
}
|
||||||
|
@ -585,6 +585,40 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @brief Class used for calculating a sparse optical flow.
|
||||||
|
|
||||||
|
The class can calculate an optical flow for a sparse feature set using the
|
||||||
|
iterative Lucas-Kanade method with pyramids.
|
||||||
|
|
||||||
|
@sa calcOpticalFlowPyrLK
|
||||||
|
|
||||||
|
*/
|
||||||
|
class CV_EXPORTS SparsePyrLKOpticalFlow : public SparseOpticalFlow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Size getWinSize() const = 0;
|
||||||
|
virtual void setWinSize(Size winSize) = 0;
|
||||||
|
|
||||||
|
virtual int getMaxLevel() const = 0;
|
||||||
|
virtual void setMaxLevel(int maxLevel) = 0;
|
||||||
|
|
||||||
|
virtual TermCriteria getTermCriteria() const = 0;
|
||||||
|
virtual void setTermCriteria(TermCriteria& crit) = 0;
|
||||||
|
|
||||||
|
virtual int getFlags() const = 0;
|
||||||
|
virtual void setFlags(int flags) = 0;
|
||||||
|
|
||||||
|
virtual double getMinEigThreshold() const = 0;
|
||||||
|
virtual void setMinEigThreshold(double minEigThreshold) = 0;
|
||||||
|
|
||||||
|
static Ptr<SparsePyrLKOpticalFlow> create(
|
||||||
|
Size winSize = Size(21, 21),
|
||||||
|
int maxLevel = 3, TermCriteria crit =
|
||||||
|
TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),
|
||||||
|
int flags = 0,
|
||||||
|
double minEigThreshold = 1e-4);
|
||||||
|
};
|
||||||
|
|
||||||
//! @} video_track
|
//! @} video_track
|
||||||
|
|
||||||
} // cv
|
} // cv
|
||||||
|
@ -837,10 +837,11 @@ int cv::buildOpticalFlowPyramid(InputArray _img, OutputArrayOfArrays pyramid, Si
|
|||||||
return maxLevel;
|
return maxLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_OPENCL
|
|
||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
class PyrLKOpticalFlow
|
namespace
|
||||||
|
{
|
||||||
|
class SparsePyrLKOpticalFlowImpl : public SparsePyrLKOpticalFlow
|
||||||
{
|
{
|
||||||
struct dim3
|
struct dim3
|
||||||
{
|
{
|
||||||
@ -848,17 +849,40 @@ namespace cv
|
|||||||
dim3() : x(0), y(0), z(0) { }
|
dim3() : x(0), y(0), z(0) { }
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
PyrLKOpticalFlow()
|
SparsePyrLKOpticalFlowImpl(Size winSize_ = Size(21,21),
|
||||||
|
int maxLevel_ = 3,
|
||||||
|
TermCriteria criteria_ = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),
|
||||||
|
int flags_ = 0,
|
||||||
|
double minEigThreshold_ = 1e-4) :
|
||||||
|
winSize(winSize_), maxLevel(maxLevel_), criteria(criteria_), flags(flags_), minEigThreshold(minEigThreshold_)
|
||||||
|
#ifdef HAVE_OPENCL
|
||||||
|
, iters(criteria_.maxCount), derivLambda(criteria_.epsilon), useInitialFlow(0 != (flags_ & OPTFLOW_LK_GET_MIN_EIGENVALS)), waveSize(0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
winSize = Size(21, 21);
|
|
||||||
maxLevel = 3;
|
|
||||||
iters = 30;
|
|
||||||
derivLambda = 0.5;
|
|
||||||
useInitialFlow = false;
|
|
||||||
|
|
||||||
waveSize = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Size getWinSize() const {return winSize;}
|
||||||
|
virtual void setWinSize(Size winSize_){winSize = winSize_;}
|
||||||
|
|
||||||
|
virtual int getMaxLevel() const {return maxLevel;}
|
||||||
|
virtual void setMaxLevel(int maxLevel_){maxLevel = maxLevel_;}
|
||||||
|
|
||||||
|
virtual TermCriteria getTermCriteria() const {return criteria;}
|
||||||
|
virtual void setTermCriteria(TermCriteria& crit_){criteria=crit_;}
|
||||||
|
|
||||||
|
virtual int getFlags() const {return flags; }
|
||||||
|
virtual void setFlags(int flags_){flags=flags_;}
|
||||||
|
|
||||||
|
virtual double getMinEigThreshold() const {return minEigThreshold;}
|
||||||
|
virtual void setMinEigThreshold(double minEigThreshold_){minEigThreshold=minEigThreshold_;}
|
||||||
|
|
||||||
|
virtual void calc(InputArray prevImg, InputArray nextImg,
|
||||||
|
InputArray prevPts, InputOutputArray nextPts,
|
||||||
|
OutputArray status,
|
||||||
|
OutputArray err = cv::noArray());
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef HAVE_OPENCL
|
||||||
bool checkParam()
|
bool checkParam()
|
||||||
{
|
{
|
||||||
iters = std::min(std::max(iters, 0), 100);
|
iters = std::min(std::max(iters, 0), 100);
|
||||||
@ -930,14 +954,17 @@ namespace cv
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Size winSize;
|
Size winSize;
|
||||||
int maxLevel;
|
int maxLevel;
|
||||||
|
TermCriteria criteria;
|
||||||
|
int flags;
|
||||||
|
double minEigThreshold;
|
||||||
|
#ifdef HAVE_OPENCL
|
||||||
int iters;
|
int iters;
|
||||||
double derivLambda;
|
double derivLambda;
|
||||||
bool useInitialFlow;
|
bool useInitialFlow;
|
||||||
|
|
||||||
private:
|
|
||||||
int waveSize;
|
int waveSize;
|
||||||
bool initWaveSize()
|
bool initWaveSize()
|
||||||
{
|
{
|
||||||
@ -1017,15 +1044,11 @@ namespace cv
|
|||||||
{
|
{
|
||||||
return (cv::ocl::Device::TYPE_CPU == cv::ocl::Device::getDefault().type());
|
return (cv::ocl::Device::TYPE_CPU == cv::ocl::Device::getDefault().type());
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static bool ocl_calcOpticalFlowPyrLK(InputArray _prevImg, InputArray _nextImg,
|
bool ocl_calcOpticalFlowPyrLK(InputArray _prevImg, InputArray _nextImg,
|
||||||
InputArray _prevPts, InputOutputArray _nextPts,
|
InputArray _prevPts, InputOutputArray _nextPts,
|
||||||
OutputArray _status, OutputArray _err,
|
OutputArray _status, OutputArray _err)
|
||||||
Size winSize, int maxLevel,
|
|
||||||
TermCriteria criteria,
|
|
||||||
int flags/*, double minEigThreshold*/ )
|
|
||||||
{
|
{
|
||||||
if (0 != (OPTFLOW_LK_GET_MIN_EIGENVALS & flags))
|
if (0 != (OPTFLOW_LK_GET_MIN_EIGENVALS & flags))
|
||||||
return false;
|
return false;
|
||||||
@ -1045,7 +1068,6 @@ namespace cv
|
|||||||
if ((1 != _prevPts.size().height) && (1 != _prevPts.size().width))
|
if ((1 != _prevPts.size().height) && (1 != _prevPts.size().width))
|
||||||
return false;
|
return false;
|
||||||
size_t npoints = _prevPts.total();
|
size_t npoints = _prevPts.total();
|
||||||
bool useInitialFlow = (0 != (flags & OPTFLOW_USE_INITIAL_FLOW));
|
|
||||||
if (useInitialFlow)
|
if (useInitialFlow)
|
||||||
{
|
{
|
||||||
if (_nextPts.empty() || _nextPts.type() != CV_32FC2 || (!_prevPts.isContinuous()))
|
if (_nextPts.empty() || _nextPts.type() != CV_32FC2 || (!_prevPts.isContinuous()))
|
||||||
@ -1060,14 +1082,7 @@ namespace cv
|
|||||||
_nextPts.create(_prevPts.size(), _prevPts.type());
|
_nextPts.create(_prevPts.size(), _prevPts.type());
|
||||||
}
|
}
|
||||||
|
|
||||||
PyrLKOpticalFlow opticalFlow;
|
if (!checkParam())
|
||||||
opticalFlow.winSize = winSize;
|
|
||||||
opticalFlow.maxLevel = maxLevel;
|
|
||||||
opticalFlow.iters = criteria.maxCount;
|
|
||||||
opticalFlow.derivLambda = criteria.epsilon;
|
|
||||||
opticalFlow.useInitialFlow = useInitialFlow;
|
|
||||||
|
|
||||||
if (!opticalFlow.checkParam())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
UMat umatErr;
|
UMat umatErr;
|
||||||
@ -1082,28 +1097,19 @@ namespace cv
|
|||||||
_status.create((int)npoints, 1, CV_8UC1);
|
_status.create((int)npoints, 1, CV_8UC1);
|
||||||
UMat umatNextPts = _nextPts.getUMat();
|
UMat umatNextPts = _nextPts.getUMat();
|
||||||
UMat umatStatus = _status.getUMat();
|
UMat umatStatus = _status.getUMat();
|
||||||
return opticalFlow.sparse(_prevImg.getUMat(), _nextImg.getUMat(), _prevPts.getUMat(), umatNextPts, umatStatus, umatErr);
|
return sparse(_prevImg.getUMat(), _nextImg.getUMat(), _prevPts.getUMat(), umatNextPts, umatStatus, umatErr);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
void cv::calcOpticalFlowPyrLK( InputArray _prevImg, InputArray _nextImg,
|
void SparsePyrLKOpticalFlowImpl::calc( InputArray _prevImg, InputArray _nextImg,
|
||||||
InputArray _prevPts, InputOutputArray _nextPts,
|
InputArray _prevPts, InputOutputArray _nextPts,
|
||||||
OutputArray _status, OutputArray _err,
|
OutputArray _status, OutputArray _err)
|
||||||
Size winSize, int maxLevel,
|
|
||||||
TermCriteria criteria,
|
|
||||||
int flags, double minEigThreshold )
|
|
||||||
{
|
{
|
||||||
#ifdef HAVE_OPENCL
|
CV_OCL_RUN(ocl::useOpenCL() &&
|
||||||
bool use_opencl = ocl::useOpenCL() &&
|
(_prevImg.isUMat() || _nextImg.isUMat()) &&
|
||||||
(_prevImg.isUMat() || _nextImg.isUMat()) &&
|
ocl::Image2D::isFormatSupported(CV_32F, 1, false),
|
||||||
ocl::Image2D::isFormatSupported(CV_32F, 1, false);
|
ocl_calcOpticalFlowPyrLK(_prevImg, _nextImg, _prevPts, _nextPts, _status, _err))
|
||||||
if ( use_opencl && ocl_calcOpticalFlowPyrLK(_prevImg, _nextImg, _prevPts, _nextPts, _status, _err, winSize, maxLevel, criteria, flags/*, minEigThreshold*/))
|
|
||||||
{
|
|
||||||
CV_IMPL_ADD(CV_IMPL_OCL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Mat prevPtsMat = _prevPts.getMat();
|
Mat prevPtsMat = _prevPts.getMat();
|
||||||
const int derivDepth = DataType<cv::detail::deriv_type>::depth;
|
const int derivDepth = DataType<cv::detail::deriv_type>::depth;
|
||||||
@ -1262,6 +1268,22 @@ void cv::calcOpticalFlowPyrLK( InputArray _prevImg, InputArray _nextImg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace cv
|
||||||
|
cv::Ptr<cv::SparsePyrLKOpticalFlow> cv::SparsePyrLKOpticalFlow::create(Size winSize, int maxLevel, TermCriteria crit, int flags, double minEigThreshold){
|
||||||
|
return makePtr<SparsePyrLKOpticalFlowImpl>(winSize,maxLevel,crit,flags,minEigThreshold);
|
||||||
|
}
|
||||||
|
void cv::calcOpticalFlowPyrLK( InputArray _prevImg, InputArray _nextImg,
|
||||||
|
InputArray _prevPts, InputOutputArray _nextPts,
|
||||||
|
OutputArray _status, OutputArray _err,
|
||||||
|
Size winSize, int maxLevel,
|
||||||
|
TermCriteria criteria,
|
||||||
|
int flags, double minEigThreshold )
|
||||||
|
{
|
||||||
|
Ptr<cv::SparsePyrLKOpticalFlow> optflow = cv::SparsePyrLKOpticalFlow::create(winSize,maxLevel,criteria,flags,minEigThreshold);
|
||||||
|
optflow->calc(_prevImg,_nextImg,_prevPts,_nextPts,_status,_err);
|
||||||
|
}
|
||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user