static void icvFloodFill_CnIR( uchar* pImage, int step, CvSize roi, CvPoint seed, _Tp newVal, CvConnectedComp* region, int flags, std::vector<CvFFillSegment>* buffer ) { _Tp* img = (_Tp*)(pImage + step * seed.y); int i, L, R; int area = 0; int XMin, XMax, YMin = seed.y, YMax = seed.y; int _8_connectivity = (flags & 255) == 8; CvFFillSegment* buffer_end = &buffer->front() + buffer->size(), *head = &buffer->front(), *tail = &buffer->front(); L = R = XMin = XMax = seed.x; _Tp val0 = img[L]; img[L] = newVal; while( ++R < roi.width && img[R] == val0 ) img[R] = newVal; while( --L >= 0 && img[L] == val0 ) img[L] = newVal; XMax = --R; XMin = ++L; ICV_PUSH( seed.y, L, R, R + 1, R, UP ); while( head != tail ) { int k, YC, PL, PR, dir; ICV_POP( YC, L, R, PL, PR, dir ); int data[][3] = { {-dir, L - _8_connectivity, R + _8_connectivity}, {dir, L - _8_connectivity, PL - 1}, {dir, PR + 1, R + _8_connectivity} }; if( region ) { area += R - L + 1; 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++ ) { dir = data[k][0]; img = (_Tp*)(pImage + (YC + dir) * step); int left = data[k][1]; int right = data[k][2]; if( (unsigned)(YC + dir) >= (unsigned)roi.height ) continue; for( i = left; i <= right; i++ ) { if( (unsigned)i < (unsigned)roi.width && img[i] == val0 ) { int j = i; img[i] = newVal; while( --j >= 0 && img[j] == val0 ) img[j] = newVal; while( ++i < roi.width && img[i] == val0 ) img[i] = newVal; ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } } } if( region ) { 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 = cv::Scalar(newVal); } }
static void icvFloodFillGrad_CnIR( uchar* pImage, int step, uchar* pMask, int maskStep, CvSize /*roi*/, CvPoint seed, _Tp newVal, Diff diff, CvConnectedComp* region, int flags, std::vector<CvFFillSegment>* buffer ) { _Tp* img = (_Tp*)(pImage + step*seed.y); uchar* mask = (pMask += maskStep + 1) + maskStep*seed.y; int i, L, R; int area = 0; _WTp sum = _WTp((typename cv::DataType<_Tp>::channel_type)0); int XMin, XMax, YMin = seed.y, YMax = seed.y; int _8_connectivity = (flags & 255) == 8; int fixedRange = flags & CV_FLOODFILL_FIXED_RANGE; int fillImage = (flags & CV_FLOODFILL_MASK_ONLY) == 0; uchar newMaskVal = (uchar)(flags & 0xff00 ? flags >> 8 : 1); CvFFillSegment* buffer_end = &buffer->front() + buffer->size(), *head = &buffer->front(), *tail = &buffer->front(); L = R = seed.x; if( mask[L] ) return; mask[L] = newMaskVal; _Tp val0 = img[L]; if( fixedRange ) { while( !mask[R + 1] && diff( img + (R+1), &val0 )) mask[++R] = newMaskVal; while( !mask[L - 1] && diff( img + (L-1), &val0 )) mask[--L] = newMaskVal; } else { while( !mask[R + 1] && diff( img + (R+1), img + R )) mask[++R] = newMaskVal; while( !mask[L - 1] && diff( img + (L-1), img + L )) mask[--L] = newMaskVal; } XMax = R; XMin = L; ICV_PUSH( seed.y, L, R, R + 1, R, UP ); while( head != tail ) { int k, YC, PL, PR, dir; ICV_POP( YC, L, R, PL, PR, dir ); int data[][3] = { {-dir, L - _8_connectivity, R + _8_connectivity}, {dir, L - _8_connectivity, PL - 1}, {dir, PR + 1, R + _8_connectivity} }; unsigned length = (unsigned)(R-L); if( region ) { area += (int)length + 1; 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++ ) { dir = data[k][0]; img = (_Tp*)(pImage + (YC + dir) * step); _Tp* img1 = (_Tp*)(pImage + YC * step); mask = pMask + (YC + dir) * maskStep; int left = data[k][1]; int right = data[k][2]; if( fixedRange ) for( i = left; i <= right; i++ ) { if( !mask[i] && diff( img + i, &val0 )) { int j = i; mask[i] = newMaskVal; while( !mask[--j] && diff( img + j, &val0 )) mask[j] = newMaskVal; while( !mask[++i] && diff( img + i, &val0 )) mask[i] = newMaskVal; ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } else if( !_8_connectivity ) for( i = left; i <= right; i++ ) { if( !mask[i] && diff( img + i, img1 + i )) { int j = i; mask[i] = newMaskVal; while( !mask[--j] && diff( img + j, img + (j+1) )) mask[j] = newMaskVal; while( !mask[++i] && (diff( img + i, img + (i-1) ) || (diff( img + i, img1 + i) && i <= R))) mask[i] = newMaskVal; ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } else for( i = left; i <= right; i++ ) { int idx; _Tp val; if( !mask[i] && (((val = img[i], (unsigned)(idx = i-L-1) <= length) && diff( &val, img1 + (i-1))) || ((unsigned)(++idx) <= length && diff( &val, img1 + i )) || ((unsigned)(++idx) <= length && diff( &val, img1 + (i+1) )))) { int j = i; mask[i] = newMaskVal; while( !mask[--j] && diff( img + j, img + (j+1) )) mask[j] = newMaskVal; while( !mask[++i] && ((val = img[i], diff( &val, img + (i-1) )) || (((unsigned)(idx = i-L-1) <= length && diff( &val, img1 + (i-1) ))) || ((unsigned)(++idx) <= length && diff( &val, img1 + i )) || ((unsigned)(++idx) <= length && diff( &val, img1 + (i+1) )))) mask[i] = newMaskVal; ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } } img = (_Tp*)(pImage + YC * step); if( fillImage ) for( i = L; i <= R; i++ ) img[i] = newVal; else if( region ) for( i = L; i <= R; i++ ) sum += img[i]; } if( region ) { region->area = area; region->rect.x = XMin; region->rect.y = YMin; region->rect.width = XMax - XMin + 1; region->rect.height = YMax - YMin + 1; if( fillImage ) region->value = cv::Scalar(newVal); else { double iarea = area ? 1./area : 0; region->value = cv::Scalar(sum*iarea); } } }
static void icvFloodGrad_CnIR( uchar* idImage, int stepId, uchar* image, int stepY, CvSize roi, CvPoint seed, int newVal, CvConnectedComp* region, std::vector<CvFFillSegment>* buffer, long threshold, int maxSize, long (*diff)(const _Tp*, const _Tp*), cv::Mat& segmImg ) { int* idImg = (int*)(idImage + stepId * seed.y); _Tp* imgPtr = (_Tp*)(image + stepY * seed.y); threshold = abs(threshold); int i, L, R; int area = 0; int XMin, XMax, YMin = seed.y, YMax = seed.y; int _8_connectivity = 1; CvFFillSegment* buffer_end = &buffer->front() + buffer->size(), *head = &buffer->front(), *tail = &buffer->front(); L = R = XMin = XMax = seed.x; idImg[L] = newVal; while( (R + 1) < roi.width && idImg[R + 1] != newVal && (diff( imgPtr + (R+1), imgPtr + R ) < threshold)) idImg[++R] = newVal; while( (L - 1) > 0 && idImg[L - 1] != newVal && (diff( imgPtr + (L-1), imgPtr + L ) < threshold)) idImg[--L] = newVal; XMax = R; XMin = L; assert(R < roi.width); ICV_PUSH( seed.y, L, R, R + 1, R, UP ); while( head != tail ) { int k, YC, PL, PR, dir; ICV_POP( YC, L, R, PL, PR, dir ); int data[][3] = { {-dir, L - _8_connectivity, R + _8_connectivity}, {dir, L - _8_connectivity, PL - 1}, {dir, PR + 1, R + _8_connectivity} }; unsigned length = (unsigned)(R-L); if( (unsigned)(YC + dir) >= (unsigned)roi.height ) continue; if( region ) { if(area > maxSize) { region->area = -1; return; } assert(R < roi.width); if( XMax < R ) XMax = R; if( XMin > L ) XMin = L; assert(XMin >= 0); assert(YC < roi.height); if( YMax < YC ) YMax = YC; if( YMin > YC ) YMin = YC; assert(YMin >= 0); } for( k = 0; k < 3; k++ ) { dir = data[k][0]; if( (unsigned)(YC + dir) >= (unsigned)roi.height ) continue; assert((YC + dir) < roi.height); assert((YC) < roi.height); idImg = (int*)(idImage + (YC + dir) * stepId); #ifndef NDEBUG uchar* simg = segmImg.ptr<uchar>((YC + dir)); #endif imgPtr = (_Tp*)(image + stepY * (YC + dir)); _Tp* img1 = (_Tp*)(image + YC * stepY); int left = data[k][1]; int right = data[k][2]; if( (unsigned)(YC + dir) >= (unsigned)roi.height ) continue; for( i = left; i <= right; i++ ) { int idx; _Tp val; if( i >= roi.width ) continue; if( idImg[i] != newVal && (((val = imgPtr[i], (unsigned)(idx = i-L-1) <= length) && (diff( &val, img1 + (i-1)) < threshold)) || ((unsigned)(++idx) <= length && (diff( &val, img1 + i ) < threshold)) || ((unsigned)(++idx) <= length && (diff( &val, img1 + (i+1) ) < threshold)) )) { int j = i; assert(i < roi.width); idImg[i] = newVal; #ifndef NDEBUG simg[i] = MAX(150, simg[i]); #endif area++; while( j > 0 && idImg[--j] != newVal && (diff( imgPtr + j, imgPtr + (j+1) ) < threshold) ) { assert(j < (roi.width - 1)); idImg[j] = newVal; #ifndef NDEBUG simg[j] = MAX(150, simg[j]); #endif area++; } while( ++i < roi.width && idImg[i] != newVal && ((val = imgPtr[i], diff( &val, imgPtr + (i-1) ) < threshold) || (((unsigned)(idx = i-L-1) <= length && diff( &val, img1 + (i-1) ) < threshold)) || ((unsigned)(++idx) <= length && diff( &val, img1 + i ) < threshold) || ((unsigned)(++idx) <= length && diff( &val, img1 + (i+1) ) < threshold))) { assert(i < roi.width); idImg[i] = newVal; #ifndef NDEBUG simg[i] = MAX(150, simg[i]); #endif area++; } assert((i-1) < roi.width); assert(R < roi.width); if(i > 0) ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } } } if( region ) { //cv::imshow("segm", segmImg); //cv::waitKey(0); 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 = cv::Scalar(newVal); } }
static void icvFloodFill_CnIR( uchar* idImage, int stepId, uchar* image, int stepY, CvSize roi, CvPoint seed, int newVal, CvConnectedComp* region, std::vector<CvFFillSegment>* buffer, long threshold, int maxSize, long (*distFunction)(const _Tp&, const _Tp&), cv::Mat& segmImg ) { int* idImg = (int*)(idImage + stepId * seed.y); _Tp* imgPtr = (_Tp*)(image + stepY * seed.y); _Tp& seedPtr = imgPtr[seed.x]; int i, L, R; int area = 0; int XMin, XMax, YMin = seed.y, YMax = seed.y; int _8_connectivity = 1; CvFFillSegment* buffer_end = &buffer->front() + buffer->size(), *head = &buffer->front(), *tail = &buffer->front(); L = R = XMin = XMax = seed.x; idImg[L] = newVal; while( ++R < roi.width && distFunction(seedPtr, imgPtr[R]) < threshold ) { idImg[R] = newVal; area++; } while( --L >= 0 && distFunction(seedPtr, imgPtr[L]) < threshold ) { idImg[L] = newVal; area++; } XMax = --R; XMin = ++L; ICV_PUSH( seed.y, L, R, R + 1, R, UP ); while( head != tail ) { int k, YC, PL, PR, dir; ICV_POP( YC, L, R, PL, PR, dir ); int data[][3] = { {-dir, L - _8_connectivity, R + _8_connectivity}, {dir, L - _8_connectivity, PL - 1}, {dir, PR + 1, R + _8_connectivity} }; if( region ) { if(area > maxSize) { region->area = -1; return; } 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++ ) { dir = data[k][0]; idImg = (int*)(idImage + (YC + dir) * stepId); imgPtr = (_Tp*)(image + stepY * (YC + dir)); int left = data[k][1]; int right = data[k][2]; if( (unsigned)(YC + dir) >= (unsigned)roi.height ) continue; for( i = left; i <= right; i++ ) { if( (unsigned)i < (unsigned)roi.width && idImg[i] != newVal && distFunction(seedPtr, imgPtr[i]) < threshold) { int j = i; idImg[i] = newVal; area++; #ifndef NDEBUG segmImg.at<uchar>((YC + dir), j) = MAX(150, segmImg.at<uchar>((YC + dir), j)); #endif while( --j >= 0 && distFunction(seedPtr, imgPtr[j]) < threshold ) { idImg[j] = newVal; area++; #ifndef NDEBUG segmImg.at<uchar>((YC + dir), j) = MAX(150, segmImg.at<uchar>((YC + dir), j)); #endif } while( ++i < roi.width && distFunction(seedPtr, imgPtr[i]) < threshold) { idImg[i] = newVal; area++; #ifndef NDEBUG segmImg.at<uchar>((YC + dir), i) = MAX(150, segmImg.at<uchar>((YC + dir), i)); #endif } ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } } } if( region ) { //cv::imshow("segm", segmImg); //cv::waitKey(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 = cv::Scalar(newVal); } }
static CvStatus icvFloodFill_8u_CnIR( uchar* pImage, int step, CvSize roi, CvPoint seed, uchar* _newVal, CvConnectedComp* region, int flags, CvFFillSegment* buffer, int buffer_size, int cn ) { uchar* img = pImage + step * seed.y; int i, L, R; int area = 0; int val0[] = {0,0,0}; uchar newVal[] = {0,0,0}; int XMin, XMax, YMin = seed.y, YMax = seed.y; int _8_connectivity = (flags & 255) == 8; CvFFillSegment* buffer_end = buffer + buffer_size, *head = buffer, *tail = buffer; L = R = XMin = XMax = seed.x; if( cn == 1 ) { val0[0] = img[L]; newVal[0] = _newVal[0]; img[L] = newVal[0]; while( ++R < roi.width && img[R] == val0[0] ) img[R] = newVal[0]; while( --L >= 0 && img[L] == val0[0] ) img[L] = newVal[0]; } else { assert( cn == 3 ); ICV_SET_C3( val0, img + L*3 ); ICV_SET_C3( newVal, _newVal ); ICV_SET_C3( img + L*3, newVal ); while( --L >= 0 && ICV_EQ_C3( img + L*3, val0 )) ICV_SET_C3( img + L*3, newVal ); while( ++R < roi.width && ICV_EQ_C3( img + R*3, val0 )) ICV_SET_C3( img + R*3, newVal ); } XMax = --R; XMin = ++L; ICV_PUSH( seed.y, L, R, R + 1, R, UP ); while( head != tail ) { int k, YC, PL, PR, dir; ICV_POP( YC, L, R, PL, PR, dir ); int data[][3] = { {-dir, L - _8_connectivity, R + _8_connectivity}, {dir, L - _8_connectivity, PL - 1}, {dir, PR + 1, R + _8_connectivity} }; if( region ) { area += R - L + 1; if( XMax < R ) XMax = R; if( XMin > L ) XMin = L; if( YMax < YC ) YMax = YC; if( YMin > YC ) YMin = YC; } for( k = 0/*(unsigned)(YC - dir) >= (unsigned)roi.height*/; k < 3; k++ ) { dir = data[k][0]; img = pImage + (YC + dir) * step; int left = data[k][1]; int right = data[k][2]; if( (unsigned)(YC + dir) >= (unsigned)roi.height ) continue; if( cn == 1 ) for( i = left; i <= right; i++ ) { if( (unsigned)i < (unsigned)roi.width && img[i] == val0[0] ) { int j = i; img[i] = newVal[0]; while( --j >= 0 && img[j] == val0[0] ) img[j] = newVal[0]; while( ++i < roi.width && img[i] == val0[0] ) img[i] = newVal[0]; ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } else for( i = left; i <= right; i++ ) { if( (unsigned)i < (unsigned)roi.width && ICV_EQ_C3( img + i*3, val0 )) { int j = i; ICV_SET_C3( img + i*3, newVal ); while( --j >= 0 && ICV_EQ_C3( img + j*3, val0 )) ICV_SET_C3( img + j*3, newVal ); while( ++i < roi.width && ICV_EQ_C3( img + i*3, val0 )) ICV_SET_C3( img + i*3, newVal ); ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } } } if( region ) { 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 = cvScalar(newVal[0], newVal[1], newVal[2], 0); } return CV_NO_ERR; }
static CvStatus icvFloodFill_Grad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep, CvSize /*roi*/, CvPoint seed, float* _newVal, float* _d_lw, float* _d_up, CvConnectedComp* region, int flags, CvFFillSegment* buffer, int buffer_size, int cn ) { float* img = pImage + (step /= sizeof(float))*seed.y; uchar* mask = (pMask += maskStep + 1) + maskStep*seed.y; int i, L, R; int area = 0; double sum[] = {0,0,0}, val0[] = {0,0,0}; float newVal[] = {0,0,0}; float d_lw[] = {0,0,0}; float interval[] = {0,0,0}; int XMin, XMax, YMin = seed.y, YMax = seed.y; int _8_connectivity = (flags & 255) == 8; int fixedRange = flags & CV_FLOODFILL_FIXED_RANGE; int fillImage = (flags & CV_FLOODFILL_MASK_ONLY) == 0; uchar newMaskVal = (uchar)(flags & 0xff00 ? flags >> 8 : 1); CvFFillSegment* buffer_end = buffer + buffer_size, *head = buffer, *tail = buffer; L = R = seed.x; if( mask[L] ) return CV_OK; mask[L] = newMaskVal; for( i = 0; i < cn; i++ ) { newVal[i] = _newVal[i]; d_lw[i] = 0.5f*(_d_lw[i] - _d_up[i]); interval[i] = 0.5f*(_d_lw[i] + _d_up[i]); if( fixedRange ) val0[i] = img[L*cn+i]; } if( cn == 1 ) { if( fixedRange ) { while( !mask[R + 1] && DIFF_FLT_C1( img + (R+1), val0 )) mask[++R] = newMaskVal; while( !mask[L - 1] && DIFF_FLT_C1( img + (L-1), val0 )) mask[--L] = newMaskVal; } else { while( !mask[R + 1] && DIFF_FLT_C1( img + (R+1), img + R )) mask[++R] = newMaskVal; while( !mask[L - 1] && DIFF_FLT_C1( img + (L-1), img + L )) mask[--L] = newMaskVal; } } else { if( fixedRange ) { while( !mask[R + 1] && DIFF_FLT_C3( img + (R+1)*3, val0 )) mask[++R] = newMaskVal; while( !mask[L - 1] && DIFF_FLT_C3( img + (L-1)*3, val0 )) mask[--L] = newMaskVal; } else { while( !mask[R + 1] && DIFF_FLT_C3( img + (R+1)*3, img + R*3 )) mask[++R] = newMaskVal; while( !mask[L - 1] && DIFF_FLT_C3( img + (L-1)*3, img + L*3 )) mask[--L] = newMaskVal; } } XMax = R; XMin = L; ICV_PUSH( seed.y, L, R, R + 1, R, UP ); while( head != tail ) { int k, YC, PL, PR, dir, curstep; ICV_POP( YC, L, R, PL, PR, dir ); int data[][3] = { {-dir, L - _8_connectivity, R + _8_connectivity}, {dir, L - _8_connectivity, PL - 1}, {dir, PR + 1, R + _8_connectivity} }; unsigned length = (unsigned)(R-L); if( region ) { area += (int)length + 1; if( XMax < R ) XMax = R; if( XMin > L ) XMin = L; if( YMax < YC ) YMax = YC; if( YMin > YC ) YMin = YC; } if( cn == 1 ) { for( k = 0; k < 3; k++ ) { dir = data[k][0]; curstep = dir * step; img = pImage + (YC + dir) * step; mask = pMask + (YC + dir) * maskStep; int left = data[k][1]; int right = data[k][2]; if( fixedRange ) for( i = left; i <= right; i++ ) { if( !mask[i] && DIFF_FLT_C1( img + i, val0 )) { int j = i; mask[i] = newMaskVal; while( !mask[--j] && DIFF_FLT_C1( img + j, val0 )) mask[j] = newMaskVal; while( !mask[++i] && DIFF_FLT_C1( img + i, val0 )) mask[i] = newMaskVal; ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } else if( !_8_connectivity ) for( i = left; i <= right; i++ ) { if( !mask[i] && DIFF_FLT_C1( img + i, img - curstep + i )) { int j = i; mask[i] = newMaskVal; while( !mask[--j] && DIFF_FLT_C1( img + j, img + (j+1) )) mask[j] = newMaskVal; while( !mask[++i] && (DIFF_FLT_C1( img + i, img + (i-1) ) || (DIFF_FLT_C1( img + i, img + i - curstep) && i <= R))) mask[i] = newMaskVal; ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } else for( i = left; i <= right; i++ ) { int idx; float val[1]; if( !mask[i] && ((val[0] = img[i], (unsigned)(idx = i-L-1) <= length) && DIFF_FLT_C1( val, img - curstep + (i-1) ) || (unsigned)(++idx) <= length && DIFF_FLT_C1( val, img - curstep + i ) || (unsigned)(++idx) <= length && DIFF_FLT_C1( val, img - curstep + (i+1) ))) { int j = i; mask[i] = newMaskVal; while( !mask[--j] && DIFF_FLT_C1( img + j, img + (j+1) )) mask[j] = newMaskVal; while( !mask[++i] && ((val[0] = img[i], DIFF_FLT_C1( val, img + (i-1) )) || ((unsigned)(idx = i-L-1) <= length && DIFF_FLT_C1( val, img - curstep + (i-1) )) || (unsigned)(++idx) <= length && DIFF_FLT_C1( val, img - curstep + i ) || (unsigned)(++idx) <= length && DIFF_FLT_C1( val, img - curstep + (i+1) ))) mask[i] = newMaskVal; ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } } img = pImage + YC * step; if( fillImage ) for( i = L; i <= R; i++ ) img[i] = newVal[0]; else if( region ) for( i = L; i <= R; i++ ) sum[0] += img[i]; } else { for( k = 0; k < 3; k++ ) { dir = data[k][0]; curstep = dir * step; img = pImage + (YC + dir) * step; mask = pMask + (YC + dir) * maskStep; int left = data[k][1]; int right = data[k][2]; if( fixedRange ) for( i = left; i <= right; i++ ) { if( !mask[i] && DIFF_FLT_C3( img + i*3, val0 )) { int j = i; mask[i] = newMaskVal; while( !mask[--j] && DIFF_FLT_C3( img + j*3, val0 )) mask[j] = newMaskVal; while( !mask[++i] && DIFF_FLT_C3( img + i*3, val0 )) mask[i] = newMaskVal; ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } else if( !_8_connectivity ) for( i = left; i <= right; i++ ) { if( !mask[i] && DIFF_FLT_C3( img + i*3, img - curstep + i*3 )) { int j = i; mask[i] = newMaskVal; while( !mask[--j] && DIFF_FLT_C3( img + j*3, img + (j+1)*3 )) mask[j] = newMaskVal; while( !mask[++i] && (DIFF_FLT_C3( img + i*3, img + (i-1)*3 ) || (DIFF_FLT_C3( img + i*3, img + i*3 - curstep) && i <= R))) mask[i] = newMaskVal; ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } else for( i = left; i <= right; i++ ) { int idx; float val[3]; if( !mask[i] && ((ICV_SET_C3( val, img+i*3 ), (unsigned)(idx = i-L-1) <= length) && DIFF_FLT_C3( val, img - curstep + (i-1)*3 ) || (unsigned)(++idx) <= length && DIFF_FLT_C3( val, img - curstep + i*3 ) || (unsigned)(++idx) <= length && DIFF_FLT_C3( val, img - curstep + (i+1)*3 ))) { int j = i; mask[i] = newMaskVal; while( !mask[--j] && DIFF_FLT_C3( img + j*3, img + (j+1)*3 )) mask[j] = newMaskVal; while( !mask[++i] && ((ICV_SET_C3( val, img + i*3 ), DIFF_FLT_C3( val, img + (i-1)*3 )) || ((unsigned)(idx = i-L-1) <= length && DIFF_FLT_C3( val, img - curstep + (i-1)*3 )) || (unsigned)(++idx) <= length && DIFF_FLT_C3( val, img - curstep + i*3 ) || (unsigned)(++idx) <= length && DIFF_FLT_C3( val, img - curstep + (i+1)*3 ))) mask[i] = newMaskVal; ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); } } } img = pImage + YC * step; if( fillImage ) for( i = L; i <= R; i++ ) ICV_SET_C3( img + i*3, newVal ); else if( region ) for( i = L; i <= R; i++ ) { sum[0] += img[i*3]; sum[1] += img[i*3+1]; sum[2] += img[i*3+2]; } } } if( region ) { region->area = area; region->rect.x = XMin; region->rect.y = YMin; region->rect.width = XMax - XMin + 1; region->rect.height = YMax - YMin + 1; if( fillImage ) region->value = cvScalar(newVal[0], newVal[1], newVal[2]); else { double iarea = area ? 1./area : 0; region->value = cvScalar(sum[0]*iarea, sum[1]*iarea, sum[2]*iarea); } } return CV_NO_ERR; }