From cf7f189fb2c41c5fcfd22e35c00beeead985e98d Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Sat, 25 Jun 2011 09:04:10 +0000 Subject: [PATCH] added type check to calcOpticalFlowPyrLK; added data type specifications in this function description. --- .../motion_analysis_and_object_tracking.rst | 4 +-- modules/video/src/lkpyramid.cpp | 36 ++++++++++++------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/modules/video/doc/motion_analysis_and_object_tracking.rst b/modules/video/doc/motion_analysis_and_object_tracking.rst index 8b9b28673b..8f724afbaf 100644 --- a/modules/video/doc/motion_analysis_and_object_tracking.rst +++ b/modules/video/doc/motion_analysis_and_object_tracking.rst @@ -15,9 +15,9 @@ Calculates an optical flow for a sparse feature set using the iterative Lucas-Ka :param nextImg: Second input image of the same size and the same type as ``prevImg`` . - :param prevPts: Vector of points for which the flow needs to be found. + :param prevPts: Vector of 2D points for which the flow needs to be found. The point coordinates must be single-precision floating-point numbers. - :param nextPts: Output vector of points containing the calculated new positions of input features in the second image. + :param nextPts: Output vector of 2D points (with single-precision floating-point coordinates) containing the calculated new positions of input features in the second image. When ``OPTFLOW_USE_INITIAL_FLOW`` flag is passed, the vector must have the same size as in the input. :param status: Output status vector. Each element of the vector is set to 1 if the flow for the corresponding features has been found. Otherwise, it is set to 0. diff --git a/modules/video/src/lkpyramid.cpp b/modules/video/src/lkpyramid.cpp index 9762a7d6d2..b1a5101c4c 100644 --- a/modules/video/src/lkpyramid.cpp +++ b/modules/video/src/lkpyramid.cpp @@ -67,7 +67,9 @@ void cv::calcOpticalFlowPyrLK( InputArray _prevImg, InputArray _nextImg, CV_Assert( prevImg.size() == nextImg.size() && prevImg.type() == nextImg.type() ); - size_t npoints = prevPtsMat.total(); + int npoints; + CV_Assert( (npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0 ); + if( npoints == 0 ) { _nextPts.release(); @@ -76,24 +78,31 @@ void cv::calcOpticalFlowPyrLK( InputArray _prevImg, InputArray _nextImg, return; } - CV_Assert( prevPtsMat.isContinuous() ); - const Point2f* prevPts = (const Point2f*)prevPtsMat.data; + if( !(flags & OPTFLOW_USE_INITIAL_FLOW) ) + _nextPts.create(prevPtsMat.size(), prevPtsMat.type(), -1, true); - _nextPts.create((int)npoints, 1, prevPtsMat.type(), -1, true); Mat nextPtsMat = _nextPts.getMat(); - CV_Assert( nextPtsMat.isContinuous() ); + CV_Assert( nextPtsMat.checkVector(2, CV_32F, true) == npoints ); + + const Point2f* prevPts = (const Point2f*)prevPtsMat.data; Point2f* nextPts = (Point2f*)nextPtsMat.data; _status.create((int)npoints, 1, CV_8U, -1, true); - Mat statusMat = _status.getMat(); + Mat statusMat = _status.getMat(), errMat; CV_Assert( statusMat.isContinuous() ); uchar* status = statusMat.data; - for( size_t i = 0; i < npoints; i++ ) + float* err = 0; + + for( int i = 0; i < npoints; i++ ) status[i] = true; - _err.create((int)npoints, 1, CV_32F, -1, true); - Mat errMat = _err.getMat(); - CV_Assert( errMat.isContinuous() ); - float* err = (float*)errMat.data; + + if( _err.needed() ) + { + _err.create((int)npoints, 1, CV_32F, -1, true); + errMat = _err.getMat(); + CV_Assert( errMat.isContinuous() ); + err = (float*)errMat.data; + } vector prevPyr, nextPyr; @@ -194,7 +203,7 @@ void cv::calcOpticalFlowPyrLK( InputArray _prevImg, InputArray _nextImg, copyMakeBorder( derivJ, _derivJ, winSize.height, winSize.height, winSize.width, winSize.width, BORDER_CONSTANT );*/ - for( size_t ptidx = 0; ptidx < npoints; ptidx++ ) + for( int ptidx = 0; ptidx < npoints; ptidx++ ) { Point2f prevPt = prevPts[ptidx]*(float)(1./(1 << level)); Point2f nextPt; @@ -274,7 +283,8 @@ void cv::calcOpticalFlowPyrLK( InputArray _prevImg, InputArray _nextImg, double D = A11*A22 - A12*A12; double minEig = (A22 + A11 - std::sqrt((A11-A22)*(A11-A22) + 4.*A12*A12))/(2*winSize.width*winSize.height); - err[ptidx] = (float)minEig; + if( err ) + err[ptidx] = (float)minEig; if( D < DBL_EPSILON ) {