X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=cvaux%2Fsrc%2Fcvsegment.cpp;fp=cvaux%2Fsrc%2Fcvsegment.cpp;h=0000000000000000000000000000000000000000;hb=e4c14cdbdf2fe805e79cd96ded236f57e7b89060;hp=74883a35b88e709dde4e78b9ede71590b97a4b4e;hpb=454138ff8a20f6edb9b65a910101403d8b520643;p=opencv diff --git a/cvaux/src/cvsegment.cpp b/cvaux/src/cvsegment.cpp deleted file mode 100644 index 74883a3..0000000 --- a/cvaux/src/cvsegment.cpp +++ /dev/null @@ -1,585 +0,0 @@ -/*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 = cvScalarAll(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; - d[0] = src[0] - src[-3]; - ad[0] = CV_IABS(d[0]); - - d[1] = src[1] - src[-2]; - ad[1] = CV_IABS(d[1]); - - d[2] = src[2] - src[-1]; - ad[2] = CV_IABS(d[2]); - - f0 = ad[1] > ad[0]; - f1 = ad[2] > ad[f0]; - - val = d[tab[f0*2 + f1]]; - - d[0] = src[0] - src[-src_step]; - ad[0] = CV_IABS(d[0]); - - d[1] = src[1] - src[1-src_step]; - ad[1] = CV_IABS(d[1]); - - d[2] = src[2] - src[2-src_step]; - ad[2] = CV_IABS(d[2]); - - f0 = ad[1] > ad[0]; - f1 = ad[2] > ad[f0]; - - dst[x] = (uchar)(val + d[tab[f0*2 + f1]] > thresh ? 255 : 0);*/ - dst[x] = (uchar)(val > thresh); - } - - src = src0; - } - -} -#endif - -const CvPoint icvCodeDeltas[8] = - { {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} }; - -static CvSeq* -icvGetComponent( uchar* img, int step, CvRect rect, - CvMemStorage* storage ) -{ - const char nbd = 4; - int deltas[16]; - int x, y; - CvSeq* exterior = 0; - char* ptr; - - /* initialize local state */ - CV_INIT_3X3_DELTAS( deltas, step, 1 ); - memcpy( deltas + 8, deltas, 8 * sizeof( deltas[0] )); - - ptr = (char*)(img + step*rect.y); - rect.width += rect.x; - rect.height += rect.y; - - for( y = rect.y; y < rect.height; y++, ptr += step ) - { - int prev = ptr[rect.x - 1] & -2; - - for( x = rect.x; x < rect.width; x++ ) - { - int p = ptr[x] & -2; - - //assert( exterior || ((p | prev) & -4) == 0 ); - - if( p != prev ) - { - CvSeq *seq = 0; - int is_hole = 0; - CvSeqWriter writer; - char *i0, *i1, *i3, *i4 = 0; - int prev_s = -1, s, s_end; - CvPoint pt = { x, y }; - - if( !(prev == 0 && p == 2) ) /* if not external contour */ - { - /* check hole */ - if( p != 0 || prev < 1 ) - { - prev = p; - continue; - } - - is_hole = 1; - if( !exterior ) - { - assert(0); - return 0; - } - } - - cvStartWriteSeq( CV_SEQ_CONTOUR | (is_hole ? CV_SEQ_FLAG_HOLE : 0), - sizeof(CvContour), sizeof(CvPoint), storage, &writer ); - s_end = s = is_hole ? 0 : 4; - i0 = ptr + x - is_hole; - - do - { - s = (s - 1) & 7; - i1 = i0 + deltas[s]; - if( (*i1 & -2) != 0 ) - break; - } - while( s != s_end ); - - if( s == s_end ) /* single pixel domain */ - { - *i0 = (char) (nbd | -128); - CV_WRITE_SEQ_ELEM( pt, writer ); - } - else - { - i3 = i0; - prev_s = s ^ 4; - - /* follow border */ - for( ;; ) - { - s_end = s; - - for( ;; ) - { - i4 = i3 + deltas[++s]; - if( (*i4 & -2) != 0 ) - break; - } - s &= 7; - - /* check "right" bound */ - if( (unsigned) (s - 1) < (unsigned) s_end ) - { - *i3 = (char) (nbd | -128); - } - else if( *i3 > 0 ) - { - *i3 = nbd; - } - - if( s != prev_s ) - { - CV_WRITE_SEQ_ELEM( pt, writer ); - prev_s = s; - } - - pt.x += icvCodeDeltas[s].x; - pt.y += icvCodeDeltas[s].y; - - if( i4 == i0 && i3 == i1 ) - break; - - i3 = i4; - s = (s + 4) & 7; - } /* end of border following loop */ - } - - seq = cvEndWriteSeq( &writer ); - cvContourBoundingRect( seq, 1 ); - - if( !is_hole ) - exterior = seq; - else - { - seq->v_prev = exterior; - seq->h_next = exterior->v_next; - if( seq->h_next ) - seq->h_next->h_prev = seq; - exterior->v_next = seq; - } - - prev = ptr[x] & -2; - } - } - } - - return exterior; -} - - - -CV_IMPL CvSeq* -cvSegmentImage( const CvArr* srcarr, CvArr* dstarr, - double canny_threshold, - double ffill_threshold, - CvMemStorage* storage ) -{ - CvSeq* root = 0; - CvMat* gray = 0; - CvMat* canny = 0; - //CvMat* temp = 0; - void* stack = 0; - - CV_FUNCNAME( "cvSegmentImage" ); - - __BEGIN__; - - CvMat srcstub, *src; - CvMat dststub, *dst; - CvMat* mask; - CvSize size; - CvPoint pt; - int ffill_lw_up = cvRound( fabs(ffill_threshold) ); - CvSeq* prev_seq = 0; - - CV_CALL( src = cvGetMat( srcarr, &srcstub )); - CV_CALL( dst = cvGetMat( dstarr, &dststub )); - - size = cvGetSize( src ); - - CV_CALL( gray = cvCreateMat( size.height, size.width, CV_8UC1 )); - CV_CALL( canny = cvCreateMat( size.height, size.width, CV_8UC1 )); - //CV_CALL( temp = cvCreateMat( size.height/2, size.width/2, CV_8UC3 )); - - CV_CALL( stack = cvAlloc( size.width * size.height * sizeof(Seg))); - - cvCvtColor( src, gray, CV_BGR2GRAY ); - cvCanny( gray, canny, 0/*canny_threshold*0.4*/, canny_threshold, 3 ); - cvThreshold( canny, canny, 1, 1, CV_THRESH_BINARY ); - //cvZero( canny ); - //color_derv( src, canny, canny_threshold ); - - //cvPyrDown( src, temp ); - //cvPyrUp( temp, dst ); - - //src = dst; - mask = canny; // a new name for new role - - // make a non-zero border. - cvRectangle( mask, cvPoint(0,0), cvPoint(size.width-1,size.height-1), cvScalarAll(1), 1 ); - - for( pt.y = 0; pt.y < size.height; pt.y++ ) - { - for( pt.x = 0; pt.x < size.width; pt.x++ ) - { - if( mask->data.ptr[mask->step*pt.y + pt.x] == 0 ) - { - CvConnectedComp region; - int avgVal[3] = { 0, 0, 0 }; - - icvSegmFloodFill_Stage1( src->data.ptr, src->step, - mask->data.ptr, mask->step, - size, pt, avgVal, - ffill_lw_up, ffill_lw_up, - ®ion, stack ); - - /*avgVal[0] = (avgVal[0] + 15) & -32; - if( avgVal[0] > 255 ) - avgVal[0] = 255; - avgVal[1] = (avgVal[1] + 15) & -32; - if( avgVal[1] > 255 ) - avgVal[1] = 255; - avgVal[2] = (avgVal[2] + 15) & -32; - if( avgVal[2] > 255 ) - avgVal[2] = 255;*/ - - if( storage ) - { - CvSeq* tmpseq = icvGetComponent( mask->data.ptr, mask->step, - region.rect, storage ); - if( tmpseq != 0 ) - { - ((CvContour*)tmpseq)->color = avgVal[0] + (avgVal[1] << 8) + (avgVal[2] << 16); - tmpseq->h_prev = prev_seq; - if( prev_seq ) - prev_seq->h_next = tmpseq; - else - root = tmpseq; - prev_seq = tmpseq; - } - } - - icvSegmFloodFill_Stage2( dst->data.ptr, dst->step, - mask->data.ptr, mask->step, - size, avgVal, - region.rect ); - } - } - } - - __END__; - - //cvReleaseMat( &temp ); - cvReleaseMat( &gray ); - cvReleaseMat( &canny ); - cvFree( &stack ); - - return root; -} - -/* End of file. */