\r
#else /* !defined (HAVE_CUDA) */\r
\r
-namespace cv { namespace gpu { namespace device \r
+namespace cv { namespace gpu { namespace device\r
{\r
- namespace pyrlk \r
+ namespace pyrlk\r
{\r
void loadConstants(int cn, float minEigThreshold, int2 winSize, int iters);\r
\r
- void calcSharrDeriv_gpu(DevMem2Db src, DevMem2D_<short> dx_buf, DevMem2D_<short> dy_buf, DevMem2D_<short> dIdx, DevMem2D_<short> dIdy, int cn, \r
+ void calcSharrDeriv_gpu(DevMem2Db src, DevMem2D_<short> dx_buf, DevMem2D_<short> dy_buf, DevMem2D_<short> dIdx, DevMem2D_<short> dIdy, int cn,\r
cudaStream_t stream = 0);\r
\r
void lkSparse_gpu(DevMem2Db I, DevMem2Db J, DevMem2D_<short> dIdx, DevMem2D_<short> dIdy,\r
- const float2* prevPts, float2* nextPts, uchar* status, float* err, bool GET_MIN_EIGENVALS, int ptcount, \r
+ const float2* prevPts, float2* nextPts, uchar* status, float* err, bool GET_MIN_EIGENVALS, int ptcount,\r
int level, dim3 block, dim3 patch, cudaStream_t stream = 0);\r
\r
- void lkDense_gpu(DevMem2Db I, DevMem2Db J, DevMem2D_<short> dIdx, DevMem2D_<short> dIdy, \r
+ void lkDense_gpu(DevMem2Db I, DevMem2Db J, DevMem2D_<short> dIdx, DevMem2D_<short> dIdy,\r
DevMem2Df u, DevMem2Df v, DevMem2Df* err, bool GET_MIN_EIGENVALS, cudaStream_t stream = 0);\r
}\r
}}}\r
pyr.resize(maxLevel + 1);\r
\r
Size sz = img0.size();\r
- \r
+\r
for (int level = 0; level <= maxLevel; ++level)\r
{\r
GpuMat temp;\r
}\r
}\r
\r
+namespace\r
+{\r
+ void calcPatchSize(cv::Size winSize, int cn, dim3& block, dim3& patch)\r
+ {\r
+ winSize.width *= cn;\r
+\r
+ if (winSize.width > 32 && winSize.width > 2 * winSize.height)\r
+ {\r
+ block.x = 32;\r
+ block.y = 8;\r
+ }\r
+ else\r
+ {\r
+ block.x = block.y = 16;\r
+ }\r
+\r
+ patch.x = (winSize.width + block.x - 1) / block.x;\r
+ patch.y = (winSize.height + block.y - 1) / block.y;\r
+\r
+ block.z = patch.z = 1;\r
+ }\r
+}\r
+\r
void cv::gpu::PyrLKOpticalFlow::sparse(const GpuMat& prevImg, const GpuMat& nextImg, const GpuMat& prevPts, GpuMat& nextPts, GpuMat& status, GpuMat* err)\r
{\r
using namespace cv::gpu::device::pyrlk;\r
- \r
+\r
if (prevPts.empty())\r
{\r
nextPts.release();\r
return;\r
}\r
\r
- derivLambda = std::min(std::max(derivLambda, 0.0), 1.0); \r
+ derivLambda = std::min(std::max(derivLambda, 0.0), 1.0);\r
\r
iters = std::min(std::max(iters, 0), 100);\r
\r
const int cn = prevImg.channels();\r
\r
- dim3 block;\r
-\r
- if (winSize.width * cn > 32)\r
- {\r
- block.x = 32;\r
- block.y = 8;\r
- }\r
- else\r
- {\r
- block.x = block.y = 16;\r
- }\r
-\r
- dim3 patch((winSize.width * cn + block.x - 1) / block.x, (winSize.height + block.y - 1) / block.y);\r
+ dim3 block, patch;\r
+ calcPatchSize(winSize, cn, block, patch);\r
\r
CV_Assert(derivLambda >= 0);\r
CV_Assert(maxLevel >= 0 && winSize.width > 2 && winSize.height > 2);\r
CV_Assert(prevImg.size() == nextImg.size() && prevImg.type() == nextImg.type());\r
CV_Assert(patch.x > 0 && patch.x < 6 && patch.y > 0 && patch.y < 6);\r
CV_Assert(prevPts.rows == 1 && prevPts.type() == CV_32FC2);\r
- \r
+\r
if (useInitialFlow)\r
CV_Assert(nextPts.size() == prevPts.size() && nextPts.type() == CV_32FC2);\r
else\r
\r
if (err)\r
ensureSizeIsEnough(1, prevPts.cols, CV_32FC1, *err);\r
- \r
+\r
// build the image pyramids.\r
// we pad each level with +/-winSize.{width|height}\r
// pixels to simplify the further patch extraction.\r
\r
buildImagePyramid(prevImg, prevPyr_, true);\r
buildImagePyramid(nextImg, nextPyr_, true);\r
- \r
+\r
// dI/dx ~ Ix, dI/dy ~ Iy\r
\r
ensureSizeIsEnough(prevImg.rows + winSize.height * 2, prevImg.cols + winSize.width * 2, CV_MAKETYPE(CV_16S, cn), dx_buf_);\r
ensureSizeIsEnough(prevImg.rows + winSize.height * 2, prevImg.cols + winSize.width * 2, CV_MAKETYPE(CV_16S, cn), dy_buf_);\r
- \r
+\r
loadConstants(cn, minEigThreshold, make_int2(winSize.width, winSize.height), iters);\r
\r
for (int level = maxLevel; level >= 0; level--)\r
\r
calcSharrDeriv(prevPyr_[level], dIdx, dIdy);\r
\r
- lkSparse_gpu(prevPyr_[level], nextPyr_[level], dIdx, dIdy, \r
- prevPts.ptr<float2>(), nextPts.ptr<float2>(), status.ptr(), level == 0 && err ? err->ptr<float>() : 0, getMinEigenVals, prevPts.cols, \r
+ lkSparse_gpu(prevPyr_[level], nextPyr_[level], dIdx, dIdy,\r
+ prevPts.ptr<float2>(), nextPts.ptr<float2>(), status.ptr(), level == 0 && err ? err->ptr<float>() : 0, getMinEigenVals, prevPts.cols,\r
level, block, patch);\r
}\r
}\r
{\r
using namespace cv::gpu::device::pyrlk;\r
\r
- derivLambda = std::min(std::max(derivLambda, 0.0), 1.0); \r
+ derivLambda = std::min(std::max(derivLambda, 0.0), 1.0);\r
\r
iters = std::min(std::max(iters, 0), 100);\r
\r
CV_Assert(prevImg.size() == nextImg.size() && prevImg.type() == nextImg.type());\r
CV_Assert(derivLambda >= 0);\r
CV_Assert(maxLevel >= 0 && winSize.width > 2 && winSize.height > 2);\r
- \r
+\r
if (useInitialFlow)\r
{\r
CV_Assert(u.size() == prevImg.size() && u.type() == CV_32FC1);\r
\r
if (err)\r
err->create(prevImg.size(), CV_32FC1);\r
- \r
+\r
// build the image pyramids.\r
// we pad each level with +/-winSize.{width|height}\r
// pixels to simplify the further patch extraction.\r
buildImagePyramid(nextImg, nextPyr_, true);\r
buildImagePyramid(u, uPyr_, false);\r
buildImagePyramid(v, vPyr_, false);\r
- \r
+\r
// dI/dx ~ Ix, dI/dy ~ Iy\r
\r
ensureSizeIsEnough(prevImg.rows + winSize.height * 2, prevImg.cols + winSize.width * 2, CV_16SC1, dx_buf_);\r
ensureSizeIsEnough(prevImg.rows + winSize.height * 2, prevImg.cols + winSize.width * 2, CV_16SC1, dy_buf_);\r
- \r
+\r
loadConstants(1, minEigThreshold, make_int2(winSize.width, winSize.height), iters);\r
\r
DevMem2Df derr = err ? *err : DevMem2Df();\r
\r
calcSharrDeriv(prevPyr_[level], dIdx, dIdy);\r
\r
- lkDense_gpu(prevPyr_[level], nextPyr_[level], dIdx, dIdy, uPyr_[level], vPyr_[level], \r
+ lkDense_gpu(prevPyr_[level], nextPyr_[level], dIdx, dIdy, uPyr_[level], vPyr_[level],\r
level == 0 && err ? &derr : 0, getMinEigenVals);\r
\r
if (level == 0)\r
{\r
float d = max(fabsf(ptr_u[j]), fabsf(ptr_v[j]));\r
\r
- if (d > maxDisplacement) \r
+ if (d > maxDisplacement)\r
maxDisplacement = d;\r
}\r
}\r
int main(int argc, const char* argv[])\r
{\r
const char* keys =\r
- "{ h | help | false | print help message }"\r
- "{ l | left | | specify left image }"\r
- "{ r | right | | specify right image }"\r
- "{ g | gray | false | use grayscale sources [PyrLK Sparse] }"\r
- "{ p | points | 4000 | specify points count [GoodFeatureToTrack] }";\r
+ "{ h | help | false | print help message }"\r
+ "{ l | left | | specify left image }"\r
+ "{ r | right | | specify right image }"\r
+ "{ gray | gray | false | use grayscale sources [PyrLK Sparse] }"\r
+ "{ win_size | win_size | 21 | specify windows size [PyrLK] }"\r
+ "{ max_level | max_level | 3 | specify max level [PyrLK] }"\r
+ "{ iters | iters | 30 | specify iterations count [PyrLK] }"\r
+ "{ deriv_lambda | deriv_lambda | 0.5 | specify deriv lambda [PyrLK] }"\r
+ "{ points | points | 4000 | specify points count [GoodFeatureToTrack] }"\r
+ "{ min_dist | min_dist | 0 | specify minimal distance between points [GoodFeatureToTrack] }";\r
\r
CommandLineParser cmd(argc, argv, keys);\r
\r
}\r
\r
bool useGray = cmd.get<bool>("gray");\r
+ int winSize = cmd.get<int>("win_size");\r
+ int maxLevel = cmd.get<int>("max_level");\r
+ int iters = cmd.get<int>("iters");\r
+ double derivLambda = cmd.get<double>("deriv_lambda");\r
int points = cmd.get<int>("points");\r
- \r
+ double minDist = cmd.get<double>("min_dist");\r
+\r
Mat frame0 = imread(fname0);\r
Mat frame1 = imread(fname1);\r
\r
\r
// goodFeaturesToTrack\r
\r
- GoodFeaturesToTrackDetector_GPU detector(points, 0.01, 0.0);\r
+ GoodFeaturesToTrackDetector_GPU detector(points, 0.01, minDist);\r
\r
GpuMat d_frame0Gray(frame0Gray);\r
GpuMat d_prevPts;\r
\r
PyrLKOpticalFlow d_pyrLK;\r
\r
+ d_pyrLK.winSize.width = winSize;\r
+ d_pyrLK.winSize.height = winSize;\r
+ d_pyrLK.maxLevel = maxLevel;\r
+ d_pyrLK.iters = iters;\r
+ d_pyrLK.derivLambda = derivLambda;\r
+\r
GpuMat d_frame0(frame0);\r
GpuMat d_frame1(frame1);\r
GpuMat d_frame1Gray(frame1Gray);\r
d_pyrLK.dense(d_frame0Gray, d_frame1Gray, d_u, d_v);\r
\r
// Draw flow field\r
- \r
+\r
Mat flowField;\r
getFlowField(Mat(d_u), Mat(d_v), flowField);\r
\r
imshow("PyrLK [Dense] Flow Field", flowField);\r
\r
- #ifdef HAVE_OPENGL \r
+ #ifdef HAVE_OPENGL\r
setOpenGlContext("PyrLK [Dense]");\r
\r
GpuMat d_vertex, d_colors;\r