#include \
#define CONV( A, B, C) ( (float)( A + (B<<1) + C ) )
typedef struct {
float xx; float xy; float yy; float xt; float yt;
float alpha; /* alpha = 1 / ( 1/lambda + xx + yy ) */ }
icvDerProductEx;
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: icvCalcOpticalFlowHS_8u32fR (Horn & Schunck method )
// Purpose: calculate Optical flow for 2 images using Horn & Schunck algorithm
// Context: // Parameters:
// imgA - pointer to first frame ROI // imgB - pointer to second frame ROI
// imgStep - width of single row of source images in bytes
// imgSize - size of the source image ROI // usePrevious - use previous (input) velocity field. // velocityX - pointer to horizontal and
// velocityY - vertical components of optical flow ROI
// velStep - width of single row of velocity frames in bytes
// lambda - Lagrangian multiplier //拉格朗日乘数 // criteria - criteria of termination processmaximum number of iterations//迭代终止条件
//
// Returns: CV_OK - all ok
// CV_OUTOFMEM_ERR - insufficient memory for function work
// CV_NULLPTR_ERR - if one of input pointers is NULL // CV_BADSIZE_ERR - wrong input sizes interrelation //
// Notes: 1.Optical flow to be computed for every pixel in ROI
// 2.For calculating spatial derivatives we use 3x3 Sobel operator.
// 3.We use the following border mode.
// The last row or column is replicated for the border // ( IPL_BORDER_REPLICATE in IPL ). // // //F*/
static CvStatus CV_STDCALL
icvCalcOpticalFlowHS_8u32fR( uchar* imgA, uchar* imgB, int imgStep, CvSize imgSize, int usePrevious, float* velocityX, float* velocityY, int velStep, float lambda,
CvTermCriteria criteria ) {
/* Loops indexes */ int i, j, k, address;
/* Buffers for Sobel calculations ,算子模块大小,Conv表示卷积*/ float *MemX[2]; float *MemY[2];
float ConvX, ConvY;
float GradX, GradY, GradT;
int imageWidth = imgSize.width; int imageHeight = imgSize.height;
int ConvLine; int LastLine;
int BufferSize;
float Ilambda = 1 / lambda; int iter = 0; int Stop;
/* buffers derivatives(派生) product */ icvDerProductEx *II;
float *VelBufX[2]; float *VelBufY[2];
/* variables for storing number of first pixel of image line */ int Line1; int Line2; int Line3;
int pixNumber;
/* auxiliary */ int NoMem = 0;
/* Checking bad arguments */ if( imgA == NULL )
return CV_NULLPTR_ERR; //CV_NULLPTR_ERR=--1 if( imgB == NULL )
return CV_NULLPTR_ERR;
if( imgSize.width <= 0 )
return CV_BADSIZE_ERR; if( imgSize.height <= 0 )
return CV_BADSIZE_ERR; if( imgSize.width > imgStep ) return CV_BADSIZE_ERR;
if( (velStep & 3) != 0 )
return CV_BADSIZE_ERR;
velStep /= 4;
/****************************************************************************************/ /* Allocating memory for all buffers */
/****************************************************************************************/ for( k = 0; k < 2; k++ ) {
MemX[k] = (float *) cvAlloc( (imgSize.height) * sizeof( float ));
if( MemX[k] == NULL ) NoMem = 1;
MemY[k] = (float *) cvAlloc( (imgSize.width) * sizeof( float ));
if( MemY[k] == NULL ) NoMem = 1;
VelBufX[k] = (float *) cvAlloc( imageWidth * sizeof( float ));
if( VelBufX[k] == NULL ) NoMem = 1;
VelBufY[k] = (float *) cvAlloc( imageWidth * sizeof( float ));
if( VelBufY[k] == NULL ) NoMem = 1; }
BufferSize = imageHeight * imageWidth;
II = (icvDerProductEx *) cvAlloc( BufferSize sizeof( icvDerProductEx )); if( (II == NULL) ) NoMem = 1;
if( NoMem ) {
for( k = 0; k < 2; k++ ) {
if( MemX[k] )
cvFree( &MemX[k] );
if( MemY[k] )
cvFree( &MemY[k] );
if( VelBufX[k] )
cvFree( &VelBufX[k] );
if( VelBufY[k] )
cvFree( &VelBufY[k] ); } if( II )
cvFree( &II );
return CV_OUTOFMEM_ERR; }
*
/****************************************************************************************\\
* Calculate first line of memX and memY *
\\****************************************************************************************/
MemY[0][0] = MemY[1][0] = CONV( imgA[0], imgA[0], imgA[1] ); MemX[0][0] = MemX[1][0] = CONV( imgA[0], imgA[0], imgA[imgStep] );
for( j = 1; j < imageWidth - 1; j++ ) {
MemY[0][j] = MemY[1][j] = CONV( imgA[j - 1], imgA[j], imgA[j + 1] ); }
pixNumber = imgStep;
for( i = 1; i < imageHeight - 1; i++ ) {
MemX[0][i] = MemX[1][i] = CONV( imgA[pixNumber - imgStep], imgA[pixNumber], imgA[pixNumber + imgStep] ); pixNumber += imgStep; }
MemY[0][imageWidth - 1] =
MemY[1][imageWidth - 1] = CONV( imgA[imageWidth - 2],
imgA[imageWidth - 1], imgA[imageWidth - 1] );
MemX[0][imageHeight - 1] =
MemX[1][imageHeight - 1] = CONV( imgA[pixNumber - imgStep], imgA[pixNumber], imgA[pixNumber] );
/****************************************************************************************\\ * begin scan image, calc derivatives *
\\****************************************************************************************/
ConvLine = 0;