aoptflowhs.cpp

本文深入剖析了HS光流算法的实现细节,包括初始化参数、计算图像梯度、迭代求解光流场等核心步骤,并通过对比不同终止准则的效果来验证算法的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

读源程序系列HS光流算法
#include "cvtest.h"

#if 0

/* Testing parameters */
static char FuncName[] = "cvCalcOpticalFlowHS";
static char TestName[] = "Optical flow (Horn & Schunck)";
static char TestClass[] = "Algorithm";

static long lImageWidth;
static long lImageHeight;
static float lambda;

#define EPSILON 0.0001f

static int fmaCalcOpticalFlowHS( void )
{
    /* Some Variables */
    int            i,j,k;
    
    uchar*         roiA;
    uchar*         roiB;

    float*         VelocityX;
    float*         VelocityY;

    float*         auxVelocityX;
    float*         auxVelocityY;

    float*         DerX;
    float*         DerY;
    float*         DerT;

    long            lErrors = 0;

    CvTermCriteria criteria;

    int usePrevious;

    int Stop = 0;
    int iteration = 0;
    float epsilon = 0;

    static int  read_param = 0;

    /* Initialization global parameters */
    if( !read_param )
    {
        read_param = 1;
        /* Reading test-parameters */
        trslRead( &lImageHeight, "300", "Image height" );
        trslRead( &lImageWidth, "300", "Image width" );
        trssRead( &lambda, "20", "lambda" );
    }

    /* initialization - for warning disable */
    criteria.epsilon = 0;
    criteria.max_iter = 0;
    criteria.type  = 1;

    /* Allocating memory for all frames */
    IplImage* imgA = cvCreateImage( cvSize(lImageWidth,lImageHeight), IPL_DEPTH_8U, 1 );
    IplImage* imgB = cvCreateImage( cvSize(lImageWidth,lImageHeight), IPL_DEPTH_8U, 1 );

    IplImage* testVelocityX = cvCreateImage( cvSize(lImageWidth,lImageHeight), IPL_DEPTH_32F, 1 );
    IplImage* testVelocityY = cvCreateImage( cvSize(lImageWidth,lImageHeight), IPL_DEPTH_32F, 1 );

    VelocityX = (float*)cvAlloc(  lImageWidth*lImageHeight * sizeof(float) );
    VelocityY = (float*)cvAlloc(  lImageWidth*lImageHeight * sizeof(float) );

    auxVelocityX = (float*)cvAlloc(  lImageWidth*lImageHeight * sizeof(float) );
    auxVelocityY = (float*)cvAlloc(  lImageWidth*lImageHeight * sizeof(float) );

    DerX = (float*)cvAlloc( lImageWidth*lImageHeight * sizeof(float) );
    DerY = (float*)cvAlloc( lImageWidth*lImageHeight * sizeof(float) );
    DerT = (float*)cvAlloc( lImageWidth*lImageHeight * sizeof(float) );

    /* Filling images */
    ats1bInitRandom( 0, 255, (uchar*)imgA->imageData, lImageWidth * lImageHeight );
    ats1bInitRandom( 0, 255, (uchar*)imgB->imageData, lImageWidth * lImageHeight );

    /* set ROI of images */
    roiA = (uchar*)imgA->imageData;
    roiB = (uchar*)imgB->imageData;

    /* example of 3*3 ROI*/
    /*roiA[0] = 0;
    roiA[1] = 1;
    roiA[2] = 2;
    roiA[lImageWidth] = 0;
    roiA[lImageWidth+1] = 1;
    roiA[lImageWidth+2] = 2;
    roiA[2*lImageWidth] = 0;
    roiA[2*lImageWidth+1] = 1;
    roiA[2*lImageWidth+2] = 2;

    roiB[0] = 1;
    roiB[1] = 2;
    roiB[2] = 3;
    roiB[lImageWidth] = 1;
    roiB[lImageWidth+1] = 2;
    roiB[lImageWidth+2] = 3;
    roiB[2*lImageWidth] = 1;
    roiB[2*lImageWidth+1] = 2;
    roiB[2*lImageWidth+2] = 3;*/
/****************************************************************************************\
*                  Calculate derivatives                                                 *
\****************************************************************************************/
    for (i=0; i<lImageHeight; i++)
    {
        for(j=0; j<lImageWidth; j++)
        {
            int jr,jl,it,ib;

            if ( j==lImageWidth-1 )
                jr = lImageWidth-1;
            else jr = j + 1;

            if ( j==0 )
                jl = 0;
            else jl = j - 1;

            if ( i==(lImageHeight - 1) )
                ib = lImageHeight - 1;
            else ib = i + 1;

            if ( i==0 )
                it = 0;
            else it = i - 1;

            DerX[ i*lImageWidth + j ] = (float)
                (roiA[ (it)*imgA->widthStep + jr ]
                - roiA[ (it)*imgA->widthStep + jl ]
                + 2*roiA[ (i)*imgA->widthStep + jr ]
                - 2*roiA[ (i)*imgA->widthStep + jl ]
                + roiA[ (ib)*imgA->widthStep + jr ]
                - roiA[ (ib)*imgA->widthStep + jl ])/8 ;

            DerY[ i*lImageWidth + j ] = (float)
                ( roiA[ (ib)*imgA->widthStep + jl ]
                + 2*roiA[ (ib)*imgA->widthStep + j  ]
                + roiA[ (ib)*imgA->widthStep + jr ]
                - roiA[ (it)*imgA->widthStep + jl ]
                - 2*roiA[ (it)*imgA->widthStep + j  ]
                - roiA[ (it)*imgA->widthStep + jr ])/8  ;

            DerT[ i*lImageWidth + j ] = (float)
                (roiB[i*imgB->widthStep + j] - roiA[i*imgA->widthStep + j]);
        }
    }
for( usePrevious = 0; usePrevious < 2; usePrevious++ )
{
/****************************************************************************************\
*                    Cases                                                               *
\****************************************************************************************/
    for ( k = 0; k < 4; k++ )
    {
        switch (k)
        {
        case 0:
            {
                criteria.type = CV_TERMCRIT_ITER;
                criteria.max_iter = 3;

                trsWrite( ATS_LST|ATS_CON,
                         "usePrevious = %d, criteria = ITER, max_iter = %d\n",
                         usePrevious, criteria.max_iter);

                break;
            }
        case 1:
            {
                criteria.type = CV_TERMCRIT_EPS;
                criteria.epsilon = 0.001f;
                trsWrite( ATS_LST|ATS_CON,
                         "usePrevious = %d, criteria = EPS, epsilon = %f\n",
                         usePrevious, criteria.epsilon);

                break;
            }
        case 2:
            {
                criteria.type = CV_TERMCRIT_EPS | CV_TERMCRIT_ITER;
                criteria.epsilon = 0.0001f;
                criteria.max_iter = 3;
                trsWrite( ATS_LST|ATS_CON,
                         "usePrevious = %d,"
                         "criteria = EPS|ITER,"
                         "epsilon = %f, max_iter = %d\n",
                         usePrevious, criteria.epsilon, criteria.max_iter);

                break;
            }
        case 3:
            {
                criteria.type = CV_TERMCRIT_EPS | CV_TERMCRIT_ITER;
                criteria.epsilon = 0.00001f;
                criteria.max_iter = 100;
                trsWrite( ATS_LST|ATS_CON,
                         "usePrevious = %d,"
                         "criteria = EPS|ITER,"
                         "epsilon = %f, max_iter = %d\n",
                         usePrevious, criteria.epsilon, criteria.max_iter);

                break;
            }
        }
        Stop = 0;
        
        /* Run CVL function */
        cvCalcOpticalFlowHS( imgA , imgB, usePrevious,
                             testVelocityX, testVelocityY,
                             lambda, criteria );

        /* Calc by other way */
        if (!usePrevious)
        {
            /* Filling initial velocity with zero */
            for (i = 0; i < lImageWidth * lImageHeight; i++ )
            {
                VelocityX[i] = 0 ;
                VelocityY[i] = 0 ;
            }
        }
        iteration = 0;
        while ( !Stop )
        {
            float* oldX;
            float* oldY;
            float* newX;
            float* newY;

            iteration++;

            if ( iteration & 1 )
            {
                oldX = VelocityX;
                oldY = VelocityY;
                newX = auxVelocityX;
                newY = auxVelocityY;
            }
            else
            {
                oldX = auxVelocityX;
                oldY = auxVelocityY;
                newX = VelocityX;
                newY = VelocityY;
            }

            for( i = 0; i < lImageHeight; i++)
            {
                for(j = 0; j< lImageWidth; j++)
                {
                    float aveX = 0;
                    float aveY = 0;
                    float dx,dy,dt;

                    aveX +=(j==0) ? oldX[ i*lImageWidth + j ] : oldX[ i*lImageWidth + j-1 ];
                    aveX +=(j==lImageWidth-1) ? oldX[ i*lImageWidth + j ] :
                                              oldX[ i*lImageWidth + j+1 ];
                    aveX +=(i==0) ? oldX[ i*lImageWidth + j ] : oldX[ (i-1)*lImageWidth + j ];
                    aveX +=(i==lImageHeight-1) ? oldX[ i*lImageWidth + j ] :
                                               oldX[ (i+1)*lImageWidth + j ];
                    aveX /=4;

                    aveY +=(j==0) ? oldY[ i*lImageWidth + j ] : oldY[ i*lImageWidth + j-1 ];
                    aveY +=(j==lImageWidth-1) ? oldY[ i*lImageWidth + j ] :
                                              oldY[ i*lImageWidth + j+1 ];
                    aveY +=(i==0) ? oldY[ i*lImageWidth + j ] : oldY[ (i-1)*lImageWidth + j ];
                    aveY +=(i==lImageHeight-1) ? oldY[ i*lImageWidth + j ] :
                                               oldY[ (i+1)*lImageWidth + j ];
                    aveY /=4;

                    dx = DerX[ i*lImageWidth + j ];
                    dy = DerY[ i*lImageWidth + j ];
                    dt = DerT[ i*lImageWidth + j ];

                    /* Horn & Schunck pure formulas */
                    newX[ i*lImageWidth + j ] = aveX - ( dx * aveX +
                                                       dy * aveY + dt ) * lambda * dx /
                                                       (1 + lambda * ( dx*dx + dy*dy ));

                    newY[ i*lImageWidth + j ] = aveY - ( dx * aveX +
                                                       dy * aveY + dt ) * lambda * dy /
                                                       (1 + lambda * ( dx*dx + dy*dy ));
                }
            }
            /* evaluate epsilon */
            epsilon = 0;
            for ( i = 0; i < lImageHeight; i++)
            {
                for ( j = 0; j < lImageWidth; j++)
                {
                    epsilon = MAX((float)fabs(newX[i*lImageWidth + j]
                                              - oldX[i*lImageWidth + j]), epsilon );
                    epsilon = MAX((float)fabs(newY[i*lImageWidth + j]
                                              - oldY[i*lImageWidth + j]), epsilon );
                }
            }

            switch (criteria.type)
            {
            case CV_TERMCRIT_ITER:
                Stop = (criteria.max_iter == iteration );break;
            case CV_TERMCRIT_EPS:
                Stop = (criteria.epsilon > epsilon );break;
            case CV_TERMCRIT_ITER|CV_TERMCRIT_EPS:
                Stop = ( ( criteria.epsilon > epsilon    ) ||
                         ( criteria.max_iter == iteration ));
                break;
            }
            if (Stop)
            {
                if ( (newX != VelocityX) && (newY != VelocityY) )
                {
                    memcpy( VelocityX, newX, lImageWidth * lImageHeight * sizeof(float) );
                    memcpy( VelocityY, newY, lImageWidth * lImageHeight * sizeof(float) );
                }
            }
        }
        trsWrite( ATS_LST|ATS_CON,
                         "%d iterations are made\n", iteration );

        for( i = 0; i < lImageHeight; i++)
        {
            for(j = 0; j< lImageWidth; j++)
            {
                float tvx = ((float*)(testVelocityX->imageData + i*testVelocityX->widthStep))[j];
                float tvy = ((float*)(testVelocityY->imageData + i*testVelocityY->widthStep))[j];

                if (( fabs( tvx - VelocityX[i*lImageWidth + j])>EPSILON )||
                    ( fabs( tvy - VelocityY[i*lImageWidth + j])>EPSILON ) )
                {
                    //trsWrite( ATS_LST | ATS_CON, " ValueX %f \n",
                    //          testVelocityX[i*lROIWidth + j] );
                    //trsWrite( ATS_LST | ATS_CON, " mustX  %f \n",
                    //          VelocityX[i*lROIWidth + j] );

                    //trsWrite( ATS_LST | ATS_CON, " ValueY %f \n",
                    //          testVelocityY[i*lROIWidth + j] );
                    //trsWrite( ATS_LST | ATS_CON, " mustY  %f \n",
                    //          VelocityY[i*lROIWidth + j] );

                    //trsWrite( ATS_LST | ATS_CON, " Coordinates %d %d\n", i, j );

                    lErrors++;
                }
            }
        }
    }/* for */
    /* Filling initial velocity with zero */
    cvZero( testVelocityX );
    cvZero( testVelocityY );
    for (i = 0; i < lImageWidth * lImageHeight; i++ )
    {
        VelocityX[i] = 0 ;
        VelocityY[i] = 0 ;
    }
}

    /* Free memory */
    cvFree( &VelocityX );
    cvFree( &VelocityY );
    cvFree( &auxVelocityX );
    cvFree( &auxVelocityY );


    cvFree( &DerX );
    cvFree( &DerY );
    cvFree( &DerT );

    cvReleaseImage( &imgA );
    cvReleaseImage( &imgB );
    cvReleaseImage( &testVelocityX );
    cvReleaseImage( &testVelocityY );


    if( lErrors == 0 ) return trsResult( TRS_OK, "No errors fixed for this text" );
    else return trsResult( TRS_FAIL, "Total fixed %d errors", lErrors );
} /*fmaCalcOpticalFlowHS*/

void InitACalcOpticalFlowHS( void )
{
    /* Registering test function */
    trsReg( FuncName, TestName, TestClass, fmaCalcOpticalFlowHS );
} /* InitACalcOpticalFlowHS */

#endif

/* End of file. */

我在ardupilot/library中新添加了两个文件,编译到最后出现报错usr/bin/ld: lib/libArduPlane_libs.a(AP_CANManager.cpp.0.o): in function `AP_CANManager::init()': AP_CANManager.cpp:(.text._ZN13AP_CANManager4initEv+0x556): undefined reference to `AP_ToshibaCAN::AP_ToshibaCAN()' collect2: error: ld returned 1 exit status Waf: Leaving directory `/home/hjhj3/ardupilot/build/sitl' Build failed -> task in 'bin/arduplane' failed (exit status 1): {task 127115774264480: cxxprogram AP_Arming.cpp.53.o,AP_ExternalControl_Plane.cpp.53.o,Attitude.cpp.53.o,GCS_MAVLink_Plane.cpp.53.o,GCS_Plane.cpp.53.o,Log.cpp.53.o,Parameters.cpp.53.o,Plane.cpp.53.o,RC_Channel_Plane.cpp.53.o,VTOL_Assist.cpp.53.o,afs_plane.cpp.53.o,altitude.cpp.53.o,avoidance_adsb.cpp.53.o,commands.cpp.53.o,commands_logic.cpp.53.o,control_modes.cpp.53.o,ekf_check.cpp.53.o,events.cpp.53.o,failsafe.cpp.53.o,fence.cpp.53.o,is_flying.cpp.53.o,mode.cpp.53.o,mode_LoiterAltQLand.cpp.53.o,mode_acro.cpp.53.o,mode_auto.cpp.53.o,mode_autoland.cpp.53.o,mode_autotune.cpp.53.o,mode_avoidADSB.cpp.53.o,mode_circle.cpp.53.o,mode_cruise.cpp.53.o,mode_fbwa.cpp.53.o,mode_fbwb.cpp.53.o,mode_guided.cpp.53.o,mode_loiter.cpp.53.o,mode_manual.cpp.53.o,mode_qacro.cpp.53.o,mode_qautotune.cpp.53.o,mode_qhover.cpp.53.o,mode_qland.cpp.53.o,mode_qloiter.cpp.53.o,mode_qrtl.cpp.53.o,mode_qstabilize.cpp.53.o,mode_rtl.cpp.53.o,mode_stabilize.cpp.53.o,mode_takeoff.cpp.53.o,mode_thermal.cpp.53.o,mode_training.cpp.53.o,motor_test.cpp.53.o,navigation.cpp.53.o,parachute.cpp.53.o,pullup.cpp.53.o,qautotune.cpp.53.o,quadplane.cpp.53.o,radio.cpp.53.o,reverse_thrust.cpp.53.o,sensors.cpp.53.o,servos.cpp.53.o,soaring.cpp.53.o,system.cpp.53.o,tailsitter.cpp.53.o,takeoff.cpp.53.o,tiltrotor.cpp.53.o,tuning.cpp.53.o -> arduplane} (run with -v to display more information)
03-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值