Calculates optical flow for the set of feature points using the pyramidal Lucas-Kanade algorithm.
IppStatus ippiOpticalFlowPyrLK_<mod>(IppiPyramid* pPyr1, IppiPyramid* pPyr2, const IppiPoint2D32f* pPrev, IppiPoint_32f* pNext, Ipp8s* pStatus, Ipp32f* pError, int numFeat, int winSize, int maxLev, int maxIter, Ipp32f threshold, IppiOptFlowPyrLK_<mod>* pState);
Supported values for mod:
8u_C1R |
16u_C1R |
32f_C1R |
Pointer to the ROI in the first image pyramid structure.
Pointer to the ROI in the second image pyramid structure.
Pointer to the array of initial coordinates of the feature points.
Pointer to the array of new coordinates of feature point; as input it contains hints for new coordinates.
Pointer to the array of result indicators.
Pointer to the array of differences between neighborhoods of old and new point positions.
Number of feature points.
Size of the search window of each pyramid level.
Pyramid level to start the operation.
Maximum number of algorithm iterations for each pyramid level.
Threshold value.
Pointer to the pyramidal optical flow structure.
The function ippiOpticalFlowPyrLK is declared in the ippcv.h file. It operates with ROI (see Regions of Interest in Intel IPP).
This function implements the iterative version of the Lucas-Kanade algorithms [Bou99]. It computes with sub-pixel accuracy new coordinates of the numFeat feature points of two images at time t and t+dt. Their initial coordinates are places in the pPrev array. Computed values of new coordinates of the feature points are stored in the array pNext, that initially contains estimations of them (or hints), for example, based on the flow values for the previous image in sequence. If there are not such hints, the pNext array contains the same initial coordinates as the pPrev array.
pStatus and pError are arrays of size numFeat with the respective data type.
The images are presented by the pyramid structures pPyr1 and pPyr2 respectively (see description of the ippiPyramidInitAlloc function for more details).These structures should be initialized by calling the function ippiPyramidInitAlloc beforehand. Furthermore the function uses the pyramidal optical flow structure pState that also should be previously initialized by the function ippiOpticalFlowPyrLKInitAlloc.
The function starts operation on the highest pyramid level (smallest image) that is specified by the maxLev parameter in the centered search window whose size winSize could not exceed the corresponding value winSize that is specified in the function ippiOpticalFlowPyrLKInitAlloc. The operation for i-th feature point on the given pyramid level finishes if:
In first two cases for non-zero levels the new position coordinates are scaled to the next pyramid level and the operation continues on the next level. For zero level or for third case the operation stops, the number of the corresponding level is written to the pStatus[i] element, the new coordinates are scaled to zero level and are written to pNext[i]. The square root of the average squared difference between neighborhoods of old and new positions is written to pError[i].
Example "Pyramid Building and Optical Flow Calculation" shows how to build pyramids and calculate the optical flow for two images.
ippStsNoErr |
Indicates no error. Any other value indicates an error or a warning. |
ippStsNullPtrErr |
Indicates an error if one of the specified pointer is NULL. |
ippStsSizeErr |
Indicates an error condition if numFeat or winSize has zero or negative value. |
ippStsBadArgErr |
Indicates an error condition if maxLev or threshold has negative value, or maxIter has zero or negative value. |
void pyroptflow(
const Ipp8u *prevFrame, // previous frame
int prevStep, // its row step
const Ipp8u *nextFrame, // next frame
int nextStep, // its row step
IppiSize roiSize, // frame size
int numLevel, // pyramid level number (5)
float rate, // pyramid rate (2.0f)
Ipp16s *pKernel, // pyramid kernel
int kerSize, // pyramid kernel size (5)
IppiPoint_32f *prevPt, // coordinates on previous frame
IppiPoint_32f *nextPt, // hint to coordinates on next frame
Ipp8s *pStatus, // result indicators
Ipp32f *pError, // differences
int numFeat, // point number
int winSize, // search window size (41)
int numIter, // iteration number (5)
float threshold) // threshold (0.0001f)
{
IppiPyramid *pPyr1, *pPyr2;
IppiOptFlowPyrLK *pOF;
ippiPyramidInitAlloc (&pPyr1, numLevel, roiSize, rate);
ippiPyramidInitAlloc (&pPyr2, numLevel, roiSize, rate);
{
IppiPyramidDownState_8u_C1R **pState1 =
(IppiPyramidDownState_8u_C1R**)&(pPyr1->pState);
IppiPyramidDownState_8u_C1R **pState2 =
(IppiPyramidDownState_8u_C1R**)&(pPyr2->pState);
Ipp8u **pImg1 = pPyr1->pImage;
Ipp8u **pImg2 = pPyr2->pImage;
int *pStep1 = pPyr1->pStep;
int *pStep2 = pPyr2->pStep;
IppiSize *pRoi1 = pPyr1->pRoi;
IppiSize *pRoi2 = pPyr2->pRoi;
IppHintAlgorithm hint=ippAlgHintFast;
int i,level = pPyr1->level;
ippiPyramidLayerDownInitAlloc_8u_C1R(pState1,roiSize,rate,pKernel,kerSize,
IPPI_INTER_LINEAR);
ippiPyramidLayerDownInitAlloc_8u_C1R(pState2,roiSize,rate,pKernel,kerSize,
IPPI_INTER_LINEAR);
pImg1[0] = (Ipp8u*)prevFrame;
pImg2[0] = (Ipp8u*)nextFrame;
pStep1[0] = prevStep;
pStep2[0] = nextStep;
pRoi1[0] = pRoi2[0] = roiSize;
for (i=1; i<=level; i++) {
pPyr1->pImage[i] = ippiMalloc_8u_C1(pRoi1[i].width,pRoi1[i].height,
pStep1+i);
pPyr2->pImage[i] = ippiMalloc_8u_C1(pRoi2[i].width,pRoi2[i].height,
pStep2+i);
ippiPyramidLayerDown_8u_C1R(pImg1[i-1],pStep1[i-1],pRoi1[i-1],
pImg1[i],pStep1[i],pRoi1[i],*pState1);
ippiPyramidLayerDown_8u_C1R(pImg2[i-1],pStep2[i-1],pRoi2[i-1],
pImg2[i],pStep2[i],pRoi2[i],*pState2);
}
ippiOpticalFlowPyrLKInitAlloc_8u_C1R (&pOF,roiSize,winSize,hint);
ippiOpticalFlowPyrLK_8u_C1R (pPyr1,pPyr2,prevPt,nextPt,pStatus,pError,
numFeat,winSize,numLevel,numIter,threshold,pOF);
ippiOpticalFlowPyrLKFree_8u_C1R(pOF);
for (i=level; i>0; i--) {
if (pImg2[i]) ippiFree(pImg2[i]);
if (pImg1[i]) ippiFree(pImg1[i]);
}
ippiPyramidLayerDownFree_8u_C1R(*pState1);
ippiPyramidLayerDownFree_8u_C1R(*pState2);
}
ippiPyramidFree (pPyr2);
ippiPyramidFree (pPyr1);
}
Copyright © 2000 - 2011, Intel Corporation. All rights reserved.