📄 cvoptflowlk.cpp
字号:
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cv.h"
typedef struct
{
float xx;
float xy;
float yy;
float xt;
float yt;
}
icvDerProduct;
#define CONV( A, B, C) ((float)( A + (B<<1) + C ))
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: icvCalcOpticalFlowLK_8u32fR ( Lucas & Kanade method )
// Purpose: calculate Optical flow for 2 images using Lucas & Kanade 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
// winSize, // size of the averaging window used for grouping
// velocityX, // pointer to horizontal and
// velocityY, // vertical components of optical flow ROI
// velStep // width of single row of velocity frames in bytes
//
// 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
icvCalcOpticalFlowLK_8u32fR( uchar * imgA,
uchar * imgB,
int imgStep,
CvSize imgSize,
CvSize winSize,
float *velocityX,
float *velocityY, int velStep )
{
/* Loops indexes */
int i, j, k;
/* Gaussian separable kernels */
float GaussX[16];
float GaussY[16];
float *KerX;
float *KerY;
/* Buffers for Sobel calculations */
float *MemX[2];
float *MemY[2];
float ConvX, ConvY;
float GradX, GradY, GradT;
int winWidth = winSize.width;
int winHeight = winSize.height;
int imageWidth = imgSize.width;
int imageHeight = imgSize.height;
int HorRadius = (winWidth - 1) >> 1;
int VerRadius = (winHeight - 1) >> 1;
int PixelLine;
int ConvLine;
int BufferAddress;
int BufferHeight = 0;
int BufferWidth;
int BufferSize;
/* buffers derivatives product */
icvDerProduct *II;
/* buffers for gaussian horisontal convolution */
icvDerProduct *WII;
/* variables for storing number of first pixel of image line */
int Line1;
int Line2;
int Line3;
/* we must have 2*2 linear system coeffs
| A1B2 B1 | {u} {C1} {0}
| | { } + { } = { }
| A2 A1B2 | {v} {C2} {0}
*/
float A1B2, A2, B1, C1, C2;
int pixNumber;
/* auxiliary */
int NoMem = 0;
velStep /= sizeof(velocityX[0]);
/* Checking bad arguments */
if( imgA == NULL )
return CV_NULLPTR_ERR;
if( imgB == NULL )
return CV_NULLPTR_ERR;
if( imageHeight < winHeight )
return CV_BADSIZE_ERR;
if( imageWidth < winWidth )
return CV_BADSIZE_ERR;
if( winHeight >= 16 )
return CV_BADSIZE_ERR;
if( winWidth >= 16 )
return CV_BADSIZE_ERR;
if( !(winHeight & 1) )
return CV_BADSIZE_ERR;
if( !(winWidth & 1) )
return CV_BADSIZE_ERR;
BufferHeight = winHeight;
BufferWidth = imageWidth;
/****************************************************************************************/
/* Computing Gaussian coeffs */
/****************************************************************************************/
GaussX[0] = 1;
GaussY[0] = 1;
for( i = 1; i < winWidth; i++ )
{
GaussX[i] = 1;
for( j = i - 1; j > 0; j-- )
{
GaussX[j] += GaussX[j - 1];
}
}
for( i = 1; i < winHeight; i++ )
{
GaussY[i] = 1;
for( j = i - 1; j > 0; j-- )
{
GaussY[j] += GaussY[j - 1];
}
}
KerX = &GaussX[HorRadius];
KerY = &GaussY[VerRadius];
/****************************************************************************************/
/* 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;
}
BufferSize = BufferHeight * BufferWidth;
II = (icvDerProduct *) cvAlloc( BufferSize * sizeof( icvDerProduct ));
WII = (icvDerProduct *) cvAlloc( BufferSize * sizeof( icvDerProduct ));
if( (II == NULL) || (WII == NULL) )
NoMem = 1;
if( NoMem )
{
for( k = 0; k < 2; k++ )
{
if( MemX[k] )
cvFree( &MemX[k] );
if( MemY[k] )
cvFree( &MemY[k] );
}
if( II )
cvFree( &II );
if( WII )
cvFree( &WII );
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 and solve system */
/****************************************************************************************/
PixelLine = -VerRadius;
ConvLine = 0;
BufferAddress = -BufferWidth;
while( PixelLine < imageHeight )
{
if( ConvLine < imageHeight )
{
/*Here we calculate derivatives for line of image */
int address;
i = ConvLine;
int L1 = i - 1;
int L2 = i;
int L3 = i + 1;
int memYline = L3 & 1;
if( L1 < 0 )
L1 = 0;
if( L3 >= imageHeight )
L3 = imageHeight - 1;
BufferAddress += BufferWidth;
BufferAddress -= ((BufferAddress >= BufferSize) ? 0xffffffff : 0) & BufferSize;
address = BufferAddress;
Line1 = L1 * imgStep;
Line2 = L2 * imgStep;
Line3 = L3 * imgStep;
/* Process first pixel */
ConvX = CONV( imgA[Line1 + 1], imgA[Line2 + 1], imgA[Line3 + 1] );
ConvY = CONV( imgA[Line3], imgA[Line3], imgA[Line3 + 1] );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -