Validate parameters for using OpenCL version, before upload UMat

pull/2155/head
vbystricky 11 years ago
parent 4152135e63
commit 33fc46cdec
  1. 2
      modules/core/src/ocl.cpp
  2. 64
      modules/video/src/lkpyramid.cpp
  3. 16
      modules/video/test/ocl/test_optflowpyrlk.cpp

@ -3841,6 +3841,8 @@ struct Image2D::Impl
{ {
Impl(const UMat &src) Impl(const UMat &src)
{ {
handle = 0;
refcount = 1;
init(src); init(src);
} }
~Impl() ~Impl()

@ -611,47 +611,34 @@ namespace cv
//getMinEigenVals = false; //getMinEigenVals = false;
} }
bool sparse(const UMat &prevImg, const UMat &nextImg, const UMat &prevPts, UMat &nextPts, UMat &status, UMat &err) bool checkParam()
{ {
if (prevPts.empty()) iters = std::min(std::max(iters, 0), 100);
{
nextPts.release();
status.release();
return false;
}
derivLambda = std::min(std::max(derivLambda, 0.0), 1.0); derivLambda = std::min(std::max(derivLambda, 0.0), 1.0);
if (derivLambda < 0) if (derivLambda < 0)
return false; return false;
if (maxLevel < 0 || winSize.width <= 2 || winSize.height <= 2) if (maxLevel < 0 || winSize.width <= 2 || winSize.height <= 2)
return false; return false;
iters = std::min(std::max(iters, 0), 100);
if (prevPts.rows != 1 || prevPts.type() != CV_32FC2)
return false;
dim3 patch;
calcPatchSize(patch); calcPatchSize(patch);
if (patch.x <= 0 || patch.x >= 6 || patch.y <= 0 || patch.y >= 6) if (patch.x <= 0 || patch.x >= 6 || patch.y <= 0 || patch.y >= 6)
return false; return false;
if (!initWaveSize()) if (!initWaveSize())
return false; return false;
if (useInitialFlow) return true;
{ }
if (nextPts.size() != prevPts.size() || nextPts.type() != CV_32FC2)
return false; bool sparse(const UMat &prevImg, const UMat &nextImg, const UMat &prevPts, UMat &nextPts, UMat &status, UMat &err)
} {
else if (!checkParam())
ensureSizeIsEnough(1, prevPts.cols, prevPts.type(), nextPts); return false;
UMat temp1 = (useInitialFlow ? nextPts : prevPts).reshape(1); UMat temp1 = (useInitialFlow ? nextPts : prevPts).reshape(1);
UMat temp2 = nextPts.reshape(1); UMat temp2 = nextPts.reshape(1);
multiply(1.0f / (1 << maxLevel) /2.0f, temp1, temp2); multiply(1.0f / (1 << maxLevel) /2.0f, temp1, temp2);
ensureSizeIsEnough(1, prevPts.cols, CV_8UC1, status);
status.setTo(Scalar::all(1)); status.setTo(Scalar::all(1));
ensureSizeIsEnough(1, prevPts.cols, CV_32FC1, err);
// build the image pyramids. // build the image pyramids.
std::vector<UMat> prevPyr; prevPyr.resize(maxLevel + 1); std::vector<UMat> prevPyr; prevPyr.resize(maxLevel + 1);
std::vector<UMat> nextPyr; nextPyr.resize(maxLevel + 1); std::vector<UMat> nextPyr; nextPyr.resize(maxLevel + 1);
@ -668,9 +655,10 @@ namespace cv
// dI/dx ~ Ix, dI/dy ~ Iy // dI/dx ~ Ix, dI/dy ~ Iy
for (int level = maxLevel; level >= 0; level--) for (int level = maxLevel; level >= 0; level--)
{ {
lkSparse_run(prevPyr[level], nextPyr[level], if (!lkSparse_run(prevPyr[level], nextPyr[level], prevPts,
prevPts, nextPts, status, err, prevPts.cols, nextPts, status, err,
level, patch); prevPts.cols, level, patch))
return false;
} }
return true; return true;
} }
@ -707,6 +695,7 @@ namespace cv
} }
private: private:
int waveSize; int waveSize;
dim3 patch;
bool initWaveSize() bool initWaveSize()
{ {
waveSize = 1; waveSize = 1;
@ -764,13 +753,6 @@ namespace cv
{ {
return (cv::ocl::Device::TYPE_CPU == cv::ocl::Device::getDefault().type()); return (cv::ocl::Device::TYPE_CPU == cv::ocl::Device::getDefault().type());
} }
inline static void ensureSizeIsEnough(int rows, int cols, int type, UMat &m)
{
if (m.type() == type && m.rows >= rows && m.cols >= cols)
m = m(Rect(0, 0, cols, rows));
else
m.create(rows, cols, type);
}
}; };
@ -794,19 +776,33 @@ namespace cv
if ((0 != CV_MAT_DEPTH(typePrev)) || (0 != CV_MAT_DEPTH(typeNext))) if ((0 != CV_MAT_DEPTH(typePrev)) || (0 != CV_MAT_DEPTH(typeNext)))
return false; return false;
if (_prevPts.empty() || _prevPts.size().height != 1 || _prevPts.type() != CV_32FC2)
return false;
bool useInitialFlow = (0 != (flags & OPTFLOW_USE_INITIAL_FLOW));
if (useInitialFlow)
{
if (_nextPts.size() != _prevPts.size() || _nextPts.type() != CV_32FC2)
return false;
}
PyrLKOpticalFlow opticalFlow; PyrLKOpticalFlow opticalFlow;
opticalFlow.winSize = winSize; opticalFlow.winSize = winSize;
opticalFlow.maxLevel = maxLevel; opticalFlow.maxLevel = maxLevel;
opticalFlow.iters = criteria.maxCount; opticalFlow.iters = criteria.maxCount;
opticalFlow.derivLambda = criteria.epsilon; opticalFlow.derivLambda = criteria.epsilon;
opticalFlow.useInitialFlow = (0 != (flags & OPTFLOW_USE_INITIAL_FLOW)); opticalFlow.useInitialFlow = useInitialFlow;
if (!opticalFlow.checkParam())
return false;
UMat umatErr; UMat umatErr;
if (_err.needed()) if (_err.needed())
{ {
_err.create(_prevPts.size(), CV_8UC1); _err.create(_prevPts.size(), CV_32FC1);
umatErr = _err.getUMat(); umatErr = _err.getUMat();
} }
else
umatErr.create(_prevPts.size(), CV_32FC1);
_nextPts.create(_prevPts.size(), _prevPts.type()); _nextPts.create(_prevPts.size(), _prevPts.type());
_status.create(_prevPts.size(), CV_8UC1); _status.create(_prevPts.size(), CV_8UC1);

@ -86,10 +86,10 @@ OCL_TEST_P(PyrLKOpticalFlow, Mat)
std::vector<cv::Point2f> pts; std::vector<cv::Point2f> pts;
cv::goodFeaturesToTrack(frame0, pts, 1000, 0.01, 0.0); cv::goodFeaturesToTrack(frame0, pts, 1000, 0.01, 0.0);
std::vector<cv::Point2f> nextPtsCPU; std::vector<cv::Point2f> cpuNextPts;
std::vector<unsigned char> statusCPU; std::vector<unsigned char> cpuStatusCPU;
std::vector<float> errCPU; std::vector<float> cpuErr;
OCL_OFF(cv::calcOpticalFlowPyrLK(frame0, frame1, pts, nextPtsCPU, statusCPU, errCPU, winSize, maxLevel, criteria, flags, minEigThreshold)); OCL_OFF(cv::calcOpticalFlowPyrLK(frame0, frame1, pts, cpuNextPts, cpuStatusCPU, cpuErr, winSize, maxLevel, criteria, flags, minEigThreshold));
UMat umatNextPts, umatStatus, umatErr; UMat umatNextPts, umatStatus, umatErr;
OCL_ON(cv::calcOpticalFlowPyrLK(umatFrame0, umatFrame1, pts, umatNextPts, umatStatus, umatErr, winSize, maxLevel, criteria, flags, minEigThreshold)); OCL_ON(cv::calcOpticalFlowPyrLK(umatFrame0, umatFrame1, pts, umatNextPts, umatStatus, umatErr, winSize, maxLevel, criteria, flags, minEigThreshold));
@ -97,13 +97,13 @@ OCL_TEST_P(PyrLKOpticalFlow, Mat)
std::vector<unsigned char> status; umatStatus.copyTo(status); std::vector<unsigned char> status; umatStatus.copyTo(status);
std::vector<float> err; umatErr.copyTo(err); std::vector<float> err; umatErr.copyTo(err);
ASSERT_EQ(nextPtsCPU.size(), nextPts.size()); ASSERT_EQ(cpuNextPts.size(), nextPts.size());
ASSERT_EQ(statusCPU.size(), status.size()); ASSERT_EQ(cpuStatusCPU.size(), status.size());
size_t mistmatch = 0; size_t mistmatch = 0;
for (size_t i = 0; i < nextPts.size(); ++i) for (size_t i = 0; i < nextPts.size(); ++i)
{ {
if (status[i] != statusCPU[i]) if (status[i] != cpuStatusCPU[i])
{ {
++mistmatch; ++mistmatch;
continue; continue;
@ -112,7 +112,7 @@ OCL_TEST_P(PyrLKOpticalFlow, Mat)
if (status[i]) if (status[i])
{ {
cv::Point2i a = nextPts[i]; cv::Point2i a = nextPts[i];
cv::Point2i b = nextPtsCPU[i]; cv::Point2i b = cpuNextPts[i];
bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1; bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1;
float errdiff = 0.0f; float errdiff = 0.0f;

Loading…
Cancel
Save