cvsegment.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 587 行 · 第 1/2 页

SVN-BASE
587
字号
/*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 "_cvaux.h"

typedef struct Seg
{
    ushort y;
    ushort l;
    ushort r;
    ushort Prevl;
    ushort Prevr;
    short  fl;
}
Seg;

#define UP 1
#define DOWN -1             

#define PUSH(Y,IL,IR,IPL,IPR,FL) {  stack[StIn].y=(ushort)(Y); \
                                    stack[StIn].l=(ushort)(IL); \
                                    stack[StIn].r=(ushort)(IR); \
                                    stack[StIn].Prevl=(ushort)(IPL); \
                                    stack[StIn].Prevr=(ushort)(IPR); \
                                    stack[StIn].fl=(short)(FL); \
                                    StIn++; }

#define POP(Y,IL,IR,IPL,IPR,FL)  {  StIn--; \
                                    Y=stack[StIn].y; \
                                    IL=stack[StIn].l; \
                                    IR=stack[StIn].r;\
                                    IPL=stack[StIn].Prevl; \
                                    IPR=stack[StIn].Prevr; \
                                    FL=stack[StIn].fl; }


#define DIFF(p1,p2) ((unsigned)((p1)[0] - (p2)[0] + d_lw)<=Interval && \
                     (unsigned)((p1)[1] - (p2)[1] + d_lw)<=Interval && \
                     (unsigned)((p1)[2] - (p2)[2] + d_lw)<=Interval)

/*#define DIFF(p1,p2) (CV_IABS((p1)[0] - (p2)[0]) + \
                     CV_IABS((p1)[1] - (p2)[1]) + \
                     CV_IABS((p1)[2] - (p2)[2]) <=Interval )*/

static CvStatus
icvSegmFloodFill_Stage1( uchar* pImage, int step,
                         uchar* pMask, int maskStep,
                         CvSize /*roi*/, CvPoint seed,
                         int* newVal, int d_lw, int d_up,
                         CvConnectedComp * region,
                         void *pStack )
{
    uchar* img = pImage + step * seed.y;
    uchar* mask = pMask + maskStep * (seed.y + 1);
    unsigned Interval = (unsigned) (d_up + d_lw);
    Seg *stack = (Seg*)pStack;
    int StIn = 0;
    int i, L, R; 
    int area = 0;
    int sum[] = { 0, 0, 0 };
    int XMin, XMax, YMin = seed.y, YMax = seed.y;
    int val0[3];

    L = R = seed.x;
    img = pImage + seed.y*step;
    mask = pMask + seed.y*maskStep;
    mask[L] = 1;

    val0[0] = img[seed.x*3];
    val0[1] = img[seed.x*3 + 1];
    val0[2] = img[seed.x*3 + 2];

    while( DIFF( img + (R+1)*3, /*img + R*3*/val0 ) && !mask[R + 1] )
        mask[++R] = 2;

    while( DIFF( img + (L-1)*3, /*img + L*3*/val0 ) && !mask[L - 1] )
        mask[--L] = 2;

    XMax = R;
    XMin = L;
    PUSH( seed.y, L, R, R + 1, R, UP );

    while( StIn )
    {
        int k, YC, PL, PR, flag/*, curstep*/;

        POP( YC, L, R, PL, PR, flag );

        int data[][3] = { {-flag, L, R}, {flag, L, PL-1}, {flag,PR+1,R}};

        if( XMax < R )
            XMax = R;

        if( XMin > L )
            XMin = L;

        if( YMax < YC )
            YMax = YC;

        if( YMin > YC )
            YMin = YC;

        for( k = 0; k < 3; k++ )
        {
            flag = data[k][0];
            /*curstep = flag * step;*/
            img = pImage + (YC + flag) * step;
            mask = pMask + (YC + flag) * maskStep;
            int left = data[k][1];
            int right = data[k][2];

            for( i = left; i <= right; i++ )
            {
                if( !mask[i] && DIFF( img + i*3, /*img - curstep + i*3*/val0 ))
                {
                    int j = i;
                    mask[i] = 2;
                    while( !mask[j - 1] && DIFF( img + (j - 1)*3, /*img + j*3*/val0 ))
                        mask[--j] = 2;

                    while( !mask[i + 1] &&
                           (DIFF( img + (i+1)*3, /*img + i*3*/val0 ) ||
                           (DIFF( img + (i+1)*3, /*img + (i+1)*3 - curstep*/val0) && i < R)))
                        mask[++i] = 2;

                    PUSH( YC + flag, j, i, L, R, -flag );
                    i++;
                }
            }
        }
        
        img = pImage + YC * step;

        for( i = L; i <= R; i++ )
        {
            sum[0] += img[i*3];
            sum[1] += img[i*3 + 1];
            sum[2] += img[i*3 + 2];
        }

        area += R - L + 1;
    }
    
    region->area = area;
    region->rect.x = XMin;
    region->rect.y = YMin;
    region->rect.width = XMax - XMin + 1;
    region->rect.height = YMax - YMin + 1;
    region->value = 0;

    {
        double inv_area = area ? 1./area : 0;
        newVal[0] = cvRound( sum[0] * inv_area );
        newVal[1] = cvRound( sum[1] * inv_area );
        newVal[2] = cvRound( sum[2] * inv_area );
    }

    return CV_NO_ERR;
}


#undef PUSH
#undef POP
#undef DIFF


static CvStatus
icvSegmFloodFill_Stage2( uchar* pImage, int step,
                         uchar* pMask, int maskStep,
                         CvSize /*roi*/, int* newVal,
                         CvRect rect )
{
    uchar* img = pImage + step * rect.y + rect.x * 3;
    uchar* mask = pMask + maskStep * rect.y + rect.x;
    uchar uv[] = { (uchar)newVal[0], (uchar)newVal[1], (uchar)newVal[2] };
    int x, y;

    for( y = 0; y < rect.height; y++, img += step, mask += maskStep )
        for( x = 0; x < rect.width; x++ )
            if( mask[x] == 2 )
            {
                mask[x] = 1;
                img[x*3] = uv[0];
                img[x*3+1] = uv[1];
                img[x*3+2] = uv[2];
            }

    return CV_OK;
}

#if 0
static void color_derv( const CvArr* srcArr, CvArr* dstArr, int thresh )
{
    static int tab[] = { 0, 2, 2, 1 };
    
    uchar *src = 0, *dst = 0;
    int dst_step, src_step;
    int x, y;
    CvSize size;

    cvGetRawData( srcArr, (uchar**)&src, &src_step, &size );
    cvGetRawData( dstArr, (uchar**)&dst, &dst_step, 0 );

    memset( dst, 0, size.width*sizeof(dst[0]));
    memset( (uchar*)dst + dst_step*(size.height-1), 0, size.width*sizeof(dst[0]));
    src += 3;

    #define  CV_IABS(a)     (((a) ^ ((a) < 0 ? -1 : 0)) - ((a) < 0 ? -1 : 0))
    
    for( y = 1; y < size.height - 1; y++ )
    {
        src += src_step;
        dst += dst_step;
        uchar* src0 = src;
        
        dst[0] = dst[size.width - 1] = 0;

        for( x = 1; x < size.width - 1; x++, src += 3 )
        {
            /*int d[3];
            int ad[3];
            int f0, f1;
            int val;*/
            int m[3];
            double val;
            //double xx, yy;
            int dh[3];
            int dv[3];
            dh[0] = src[0] - src[-3];
            dv[0] = src[0] - src[-src_step];
            dh[1] = src[1] - src[-2];
            dv[1] = src[1] - src[1-src_step];
            dh[2] = src[2] - src[-1];
            dv[2] = src[2] - src[2-src_step];

            m[0] = dh[0]*dh[0] + dh[1]*dh[1] + dh[2]*dh[2];
            m[2] = dh[0]*dv[0] + dh[1]*dv[1] + dh[2]*dv[2];
            m[1] = dv[0]*dv[0] + dv[1]*dv[1] + dh[2]*dh[2];

            val = (m[0] + m[2]) + 
                sqrt(((double)((double)m[0] - m[2]))*(m[0] - m[2]) + (4.*m[1])*m[1]);

            /*

            xx = m[1];
            yy = v - m[0];
            v /= sqrt(xx*xx + yy*yy) + 1e-7;
            xx *= v;
            yy *= v;
            
            dx[x] = (short)cvRound(xx);
            dy[x] = (short)cvRound(yy);

            //dx[x] = (short)cvRound(v);

            //dx[x] = dy[x] = (short)v;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?