OpenCV中Integral Image的源码

在一个叫Google讨论班的网络文件夹上找到了一篇将real-time object detection的ppt。

里面Integral Image的Recursive形式没有完全理解,看一下源码学习一下。


ppt中只给了这个公式。

s: cumulative row 

i: original image

ii: integral image

walk的话和普通bmp一样外循环y,内循环x

计算分成两步:1.计算当前行的summation

                           2.前一行的summation+当前行的summation

位置是OpenCV-2.1.0-win\OpenCV-2.1.0\src\cv\cvsumpixels.cpp(55):void integral_( const Mat& _src, Mat& _sum, Mat& _sqsum, Mat& _tilted )

void integral_( const Mat& _src, Mat& _sum, Mat& _sqsum, Mat& _tilted )
{
    int cn = _src.channels();
    Size size = _src.size();
    int x, y, k;


    const T* src = (const T*)_src.data;
    ST* sum = (ST*)_sum.data;
    ST* tilted = (ST*)_tilted.data;
    QT* sqsum = (QT*)_sqsum.data;


    int srcstep = (int)(_src.step/sizeof(T));
    int sumstep = (int)(_sum.step/sizeof(ST));
    int tiltedstep = (int)(_tilted.step/sizeof(ST));
    int sqsumstep = (int)(_sqsum.step/sizeof(QT));


    size.width *= cn;


    memset( sum, 0, (size.width+cn)*sizeof(sum[0]));
    sum += sumstep + cn;


    if( sqsum )
    {
        memset( sqsum, 0, (size.width+cn)*sizeof(sqsum[0]));
        sqsum += sqsumstep + cn;
    }


    if( tilted )
    {
        memset( tilted, 0, (size.width+cn)*sizeof(tilted[0]));
        tilted += tiltedstep + cn;
    }


    if( sqsum == 0 && tilted == 0 )
    {
        //s( x, y ) = s( x-1, y ) + i( x, y )
        //sum( x, y) = sum( x, y-1 ) + s( x, y )
        for( y = 0; y < size.height; y++, src += srcstep - cn, sum += sumstep - cn )
        {
            for( k = 0; k < cn; k++, src++, sum++ )
            {
                ST s = sum[-cn] = 0;
                for( x = 0; x < size.width; x += cn )
                {
                    s += src[x];
                    sum[x] = sum[x - sumstep] + s;
                }
            }
        }
    }
    else if( tilted == 0 )
    {
        for( y = 0; y < size.height; y++, src += srcstep - cn,
                        sum += sumstep - cn, sqsum += sqsumstep - cn )
        {
            for( k = 0; k < cn; k++, src++, sum++, sqsum++ )
            {
                ST s = sum[-cn] = 0;
                QT sq = sqsum[-cn] = 0;
                for( x = 0; x < size.width; x += cn )
                {
                    T it = src[x];
                    s += it;
                    sq += sqr<QT>(it);
                    ST t = sum[x - sumstep] + s;
                    QT tq = sqsum[x - sqsumstep] + sq;
                    sum[x] = t;
                    sqsum[x] = tq;
                }
            }
        }
    }
    else
    {
        AutoBuffer<ST> _buf(size.width+cn);
        ST* buf = _buf;
        ST s;
        QT sq;
        for( k = 0; k < cn; k++, src++, sum++, tilted++, sqsum++, buf++ )
        {
            sum[-cn] = tilted[-cn] = 0;
            sqsum[-cn] = 0;


            for( x = 0, s = 0, sq = 0; x < size.width; x += cn )
            {
                T it = src[x];
                buf[x] = tilted[x] = it;
                s += it;
                sq += sqr<QT>(it);
                sum[x] = s;
                sqsum[x] = sq;
            }


            if( size.width == cn )
                buf[cn] = 0;
        }


        for( y = 1; y < size.height; y++ )
        {
            src += srcstep - cn;
            sum += sumstep - cn;
            sqsum += sqsumstep - cn;
            tilted += tiltedstep - cn;
            buf += -cn;


            for( k = 0; k < cn; k++, src++, sum++, sqsum++, tilted++, buf++ )
            {
                T it = src[0];
                ST t0 = s = it;
                QT tq0 = sq = sqr<QT>(it);


                sum[-cn] = 0;
                sqsum[-cn] = 0;
                tilted[-cn] = tilted[-tiltedstep];


                sum[0] = sum[-sumstep] + t0;
                sqsum[0] = sqsum[-sqsumstep] + tq0;
                tilted[0] = tilted[-tiltedstep] + t0 + buf[cn];


                for( x = cn; x < size.width - cn; x += cn )
                {
                    ST t1 = buf[x];
                    buf[x - cn] = t1 + t0;
                    t0 = it = src[x];
                    tq0 = sqr<QT>(it);
                    s += t0;
                    sq += tq0;
                    sum[x] = sum[x - sumstep] + s;
                    sqsum[x] = sqsum[x - sqsumstep] + sq;
                    t1 += buf[x + cn] + t0 + tilted[x - tiltedstep - cn];
                    tilted[x] = t1;
                }


                if( size.width > cn )
                {
                    ST t1 = buf[x];
                    buf[x - cn] = t1 + t0;
                    t0 = it = src[x];
                    tq0 = sqr<QT>(it);
                    s += t0;
                    sq += tq0;
                    sum[x] = sum[x - sumstep] + s;
                    sqsum[x] = sqsum[x - sqsumstep] + sq;
                    tilted[x] = t0 + t1 + tilted[x - tiltedstep - cn];
                    buf[x] = t0;
                }
            }
        }

    }
}





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值