📄 cvoptflowhs.cpp
字号:
/* Process middle of line */
for( j = 1; j < imageWidth - 1; j++ )
{
ConvX = CONV( imgA[Line1 + j + 1], imgA[Line2 + j + 1], imgA[Line3 + j + 1] );
ConvY = CONV( imgA[Line3 + j - 1], imgA[Line3 + j], imgA[Line3 + j + 1] );
GradY = (ConvY - MemY[memYline][j]) * 0.125f;
GradX = (ConvX - MemX[(j - 1) & 1][ConvLine]) * 0.125f;
MemY[memYline][j] = ConvY;
MemX[(j - 1) & 1][ConvLine] = ConvX;
GradT = (float) (imgB[Line2 + j] - imgA[Line2 + j]);
II[address].xx = GradX * GradX;
II[address].xy = GradX * GradY;
II[address].yy = GradY * GradY;
II[address].xt = GradX * GradT;
II[address].yt = GradY * GradT;
II[address].alpha = 1 / (Ilambda + II[address].xx + II[address].yy);
address++;
}
/* Process last pixel of line */
ConvX = CONV( imgA[Line1 + imageWidth - 1], imgA[Line2 + imageWidth - 1],
imgA[Line3 + imageWidth - 1] );
ConvY = CONV( imgA[Line3 + imageWidth - 2], imgA[Line3 + imageWidth - 1],
imgA[Line3 + imageWidth - 1] );
GradY = (ConvY - MemY[memYline][imageWidth - 1]) * 0.125f;
GradX = (ConvX - MemX[(imageWidth - 2) & 1][ConvLine]) * 0.125f;
MemY[memYline][imageWidth - 1] = ConvY;
GradT = (float) (imgB[Line2 + imageWidth - 1] - imgA[Line2 + imageWidth - 1]);
II[address].xx = GradX * GradX;
II[address].xy = GradX * GradY;
II[address].yy = GradY * GradY;
II[address].xt = GradX * GradT;
II[address].yt = GradY * GradT;
II[address].alpha = 1 / (Ilambda + II[address].xx + II[address].yy);
address++;
ConvLine++;
}
/****************************************************************************************\
* Prepare initial approximation *
\****************************************************************************************/
if( !usePrevious )
{
float *vx = velocityX;
float *vy = velocityY;
for( i = 0; i < imageHeight; i++ )
{
memset( vx, 0, imageWidth * sizeof( float ));
memset( vy, 0, imageWidth * sizeof( float ));
vx += velStep;
vy += velStep;
}
}
/****************************************************************************************\
* Perform iterations *
\****************************************************************************************/
iter = 0;
Stop = 0;
LastLine = velStep * (imageHeight - 1);
while( !Stop )
{
float Eps = 0;
address = 0;
iter++;
/****************************************************************************************\
* begin scan velocity and update it *
\****************************************************************************************/
Line2 = -velStep;
for( i = 0; i < imageHeight; i++ )
{
/* Here average velocity */
float averageX;
float averageY;
float tmp;
Line2 += velStep;
Line1 = Line2 - ((Line2 == 0) ? 0 : velStep);
Line3 = Line2 + ((Line2 == LastLine) ? 0 : velStep);
/* Process first pixel */
averageX = (velocityX[Line2] +
velocityX[Line2 + 1] + velocityX[Line1] + velocityX[Line3]) / 4;
averageY = (velocityY[Line2] +
velocityY[Line2 + 1] + velocityY[Line1] + velocityY[Line3]) / 4;
VelBufX[i & 1][0] = averageX -
(II[address].xx * averageX +
II[address].xy * averageY + II[address].xt) * II[address].alpha;
VelBufY[i & 1][0] = averageY -
(II[address].xy * averageX +
II[address].yy * averageY + II[address].yt) * II[address].alpha;
/* update Epsilon */
if( criteria.type & CV_TERMCRIT_EPS )
{
tmp = (float)fabs(velocityX[Line2] - VelBufX[i & 1][0]);
Eps = MAX( tmp, Eps );
tmp = (float)fabs(velocityY[Line2] - VelBufY[i & 1][0]);
Eps = MAX( tmp, Eps );
}
address++;
/* Process middle of line */
for( j = 1; j < imageWidth - 1; j++ )
{
averageX = (velocityX[Line2 + j - 1] +
velocityX[Line2 + j + 1] +
velocityX[Line1 + j] + velocityX[Line3 + j]) / 4;
averageY = (velocityY[Line2 + j - 1] +
velocityY[Line2 + j + 1] +
velocityY[Line1 + j] + velocityY[Line3 + j]) / 4;
VelBufX[i & 1][j] = averageX -
(II[address].xx * averageX +
II[address].xy * averageY + II[address].xt) * II[address].alpha;
VelBufY[i & 1][j] = averageY -
(II[address].xy * averageX +
II[address].yy * averageY + II[address].yt) * II[address].alpha;
/* update Epsilon */
if( criteria.type & CV_TERMCRIT_EPS )
{
tmp = (float)fabs(velocityX[Line2 + j] - VelBufX[i & 1][j]);
Eps = MAX( tmp, Eps );
tmp = (float)fabs(velocityY[Line2 + j] - VelBufY[i & 1][j]);
Eps = MAX( tmp, Eps );
}
address++;
}
/* Process last pixel of line */
averageX = (velocityX[Line2 + imageWidth - 2] +
velocityX[Line2 + imageWidth - 1] +
velocityX[Line1 + imageWidth - 1] +
velocityX[Line3 + imageWidth - 1]) / 4;
averageY = (velocityY[Line2 + imageWidth - 2] +
velocityY[Line2 + imageWidth - 1] +
velocityY[Line1 + imageWidth - 1] +
velocityY[Line3 + imageWidth - 1]) / 4;
VelBufX[i & 1][imageWidth - 1] = averageX -
(II[address].xx * averageX +
II[address].xy * averageY + II[address].xt) * II[address].alpha;
VelBufY[i & 1][imageWidth - 1] = averageY -
(II[address].xy * averageX +
II[address].yy * averageY + II[address].yt) * II[address].alpha;
/* update Epsilon */
if( criteria.type & CV_TERMCRIT_EPS )
{
tmp = (float)fabs(velocityX[Line2 + imageWidth - 1] -
VelBufX[i & 1][imageWidth - 1]);
Eps = MAX( tmp, Eps );
tmp = (float)fabs(velocityY[Line2 + imageWidth - 1] -
VelBufY[i & 1][imageWidth - 1]);
Eps = MAX( tmp, Eps );
}
address++;
/* store new velocity from old buffer to velocity frame */
if( i > 0 )
{
memcpy( &velocityX[Line1], VelBufX[(i - 1) & 1], imageWidth * sizeof( float ));
memcpy( &velocityY[Line1], VelBufY[(i - 1) & 1], imageWidth * sizeof( float ));
}
} /*for */
/* store new velocity from old buffer to velocity frame */
memcpy( &velocityX[imageWidth * (imageHeight - 1)],
VelBufX[(imageHeight - 1) & 1], imageWidth * sizeof( float ));
memcpy( &velocityY[imageWidth * (imageHeight - 1)],
VelBufY[(imageHeight - 1) & 1], imageWidth * sizeof( float ));
if( (criteria.type & CV_TERMCRIT_ITER) && (iter == criteria.max_iter) )
Stop = 1;
if( (criteria.type & CV_TERMCRIT_EPS) && (Eps < criteria.epsilon) )
Stop = 1;
}
/* Free memory */
for( k = 0; k < 2; k++ )
{
cvFree( &MemX[k] );
cvFree( &MemY[k] );
cvFree( &VelBufX[k] );
cvFree( &VelBufY[k] );
}
cvFree( &II );
return CV_OK;
} /*icvCalcOpticalFlowHS_8u32fR*/
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvCalcOpticalFlowHS
// Purpose: Optical flow implementation
// Context:
// Parameters:
// srcA, srcB - source image
// velx, vely - destination image
// Returns:
//
// Notes:
//F*/
CV_IMPL void
cvCalcOpticalFlowHS( const void* srcarrA, const void* srcarrB, int usePrevious,
void* velarrx, void* velarry,
double lambda, CvTermCriteria criteria )
{
CV_FUNCNAME( "cvCalcOpticalFlowHS" );
__BEGIN__;
CvMat stubA, *srcA = (CvMat*)srcarrA;
CvMat stubB, *srcB = (CvMat*)srcarrB;
CvMat stubx, *velx = (CvMat*)velarrx;
CvMat stuby, *vely = (CvMat*)velarry;
CV_CALL( srcA = cvGetMat( srcA, &stubA ));
CV_CALL( srcB = cvGetMat( srcB, &stubB ));
CV_CALL( velx = cvGetMat( velx, &stubx ));
CV_CALL( vely = cvGetMat( vely, &stuby ));
if( !CV_ARE_TYPES_EQ( srcA, srcB ))
CV_ERROR( CV_StsUnmatchedFormats, "Source images have different formats" );
if( !CV_ARE_TYPES_EQ( velx, vely ))
CV_ERROR( CV_StsUnmatchedFormats, "Destination images have different formats" );
if( !CV_ARE_SIZES_EQ( srcA, srcB ) ||
!CV_ARE_SIZES_EQ( velx, vely ) ||
!CV_ARE_SIZES_EQ( srcA, velx ))
CV_ERROR( CV_StsUnmatchedSizes, "" );
if( CV_MAT_TYPE( srcA->type ) != CV_8UC1 ||
CV_MAT_TYPE( velx->type ) != CV_32FC1 )
CV_ERROR( CV_StsUnsupportedFormat, "Source images must have 8uC1 type and "
"destination images must have 32fC1 type" );
if( srcA->step != srcB->step || velx->step != vely->step )
CV_ERROR( CV_BadStep, "source and destination images have different step" );
IPPI_CALL( icvCalcOpticalFlowHS_8u32fR( (uchar*)srcA->data.ptr, (uchar*)srcB->data.ptr,
srcA->step, cvGetMatSize( srcA ), usePrevious,
velx->data.fl, vely->data.fl,
velx->step, (float)lambda, criteria ));
__END__;
}
/* End of file. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -