Renesas GR-PEACH OpenCV Development / gr-peach-opencv-project-sd-card_update

Fork of gr-peach-opencv-project-sd-card by the do

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers floodfill.cpp Source File

floodfill.cpp

00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                           License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
00015 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other materials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or implied warranties, including, but not limited to, the implied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 #include "precomp.hpp"
00044 
00045 #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
00046 # pragma GCC diagnostic ignored "-Warray-bounds"
00047 #endif
00048 
00049 namespace cv
00050 {
00051 
00052 struct FFillSegment
00053 {
00054     ushort y;
00055     ushort l;
00056     ushort r;
00057     ushort prevl;
00058     ushort prevr;
00059     short dir;
00060 };
00061 
00062 enum
00063 {
00064     UP = 1,
00065     DOWN = -1
00066 };
00067 
00068 #define ICV_PUSH( Y, L, R, PREV_L, PREV_R, DIR )  \
00069 {                                                 \
00070     tail->y = (ushort)(Y);                        \
00071     tail->l = (ushort)(L);                        \
00072     tail->r = (ushort)(R);                        \
00073     tail->prevl = (ushort)(PREV_L);               \
00074     tail->prevr = (ushort)(PREV_R);               \
00075     tail->dir = (short)(DIR);                     \
00076     if( ++tail == buffer_end )                    \
00077     {                                             \
00078         buffer->resize(buffer->size() * 3/2);     \
00079         tail = &buffer->front() + (tail - head);  \
00080         head = &buffer->front();                  \
00081         buffer_end = head + buffer->size();       \
00082     }                                             \
00083 }
00084 
00085 #define ICV_POP( Y, L, R, PREV_L, PREV_R, DIR )   \
00086 {                                                 \
00087     --tail;                                       \
00088     Y = tail->y;                                  \
00089     L = tail->l;                                  \
00090     R = tail->r;                                  \
00091     PREV_L = tail->prevl;                         \
00092     PREV_R = tail->prevr;                         \
00093     DIR = tail->dir;                              \
00094 }
00095 
00096 struct ConnectedComp
00097 {
00098     ConnectedComp();
00099     Rect rect;
00100     Point pt;
00101     int threshold;
00102     int label;
00103     int area;
00104     int harea;
00105     int carea;
00106     int perimeter;
00107     int nholes;
00108     int ninflections;
00109     double mx;
00110     double my;
00111     Scalar avg;
00112     Scalar sdv;
00113 };
00114 
00115 ConnectedComp::ConnectedComp()
00116 {
00117     rect = Rect(0, 0, 0, 0);
00118     pt = Point(-1, -1);
00119     threshold = -1;
00120     label = -1;
00121     area = harea = carea = perimeter = nholes = ninflections = 0;
00122     mx = my = 0;
00123     avg = sdv = Scalar::all(0);
00124 }
00125 
00126 // Simple Floodfill (repainting single-color connected component)
00127 
00128 template<typename _Tp>
00129 static void
00130 floodFill_CnIR( Mat& image, Point seed,
00131                _Tp newVal, ConnectedComp* region, int flags,
00132                std::vector<FFillSegment>* buffer )
00133 {
00134     _Tp* img = image.ptr<_Tp>(seed.y);
00135     Size roi = image.size();
00136     int i, L, R;
00137     int area = 0;
00138     int XMin, XMax, YMin = seed.y, YMax = seed.y;
00139     int _8_connectivity = (flags & 255) == 8;
00140     FFillSegment* buffer_end = &buffer->front() + buffer->size(), *head = &buffer->front(), *tail = &buffer->front();
00141 
00142     L = R = XMin = XMax = seed.x;
00143 
00144     _Tp val0 = img[L];
00145     img[L] = newVal;
00146 
00147     while( ++R < roi.width && img[R] == val0 )
00148         img[R] = newVal;
00149 
00150     while( --L >= 0 && img[L] == val0 )
00151         img[L] = newVal;
00152 
00153     XMax = --R;
00154     XMin = ++L;
00155 
00156     ICV_PUSH( seed.y, L, R, R + 1, R, UP );
00157 
00158     while( head != tail )
00159     {
00160         int k, YC, PL, PR, dir;
00161         ICV_POP( YC, L, R, PL, PR, dir );
00162 
00163         int data[][3] =
00164         {
00165             {-dir, L - _8_connectivity, R + _8_connectivity},
00166             {dir, L - _8_connectivity, PL - 1},
00167             {dir, PR + 1, R + _8_connectivity}
00168         };
00169 
00170         if( region )
00171         {
00172             area += R - L + 1;
00173 
00174             if( XMax < R ) XMax = R;
00175             if( XMin > L ) XMin = L;
00176             if( YMax < YC ) YMax = YC;
00177             if( YMin > YC ) YMin = YC;
00178         }
00179 
00180         for( k = 0; k < 3; k++ )
00181         {
00182             dir = data[k][0];
00183 
00184             if( (unsigned)(YC + dir) >= (unsigned)roi.height )
00185                 continue;
00186 
00187             img = image.ptr<_Tp>(YC + dir);
00188             int left = data[k][1];
00189             int right = data[k][2];
00190 
00191             for( i = left; i <= right; i++ )
00192             {
00193                 if( (unsigned)i < (unsigned)roi.width && img[i] == val0 )
00194                 {
00195                     int j = i;
00196                     img[i] = newVal;
00197                     while( --j >= 0 && img[j] == val0 )
00198                         img[j] = newVal;
00199 
00200                     while( ++i < roi.width && img[i] == val0 )
00201                         img[i] = newVal;
00202 
00203                     ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir );
00204                 }
00205             }
00206         }
00207     }
00208 
00209     if( region )
00210     {
00211         region->pt = seed;
00212         region->area = area;
00213         region->rect.x = XMin;
00214         region->rect.y = YMin;
00215         region->rect.width = XMax - XMin + 1;
00216         region->rect.height = YMax - YMin + 1;
00217     }
00218 }
00219 
00220 /****************************************************************************************\
00221 *                                   Gradient Floodfill                                   *
00222 \****************************************************************************************/
00223 
00224 struct Diff8uC1
00225 {
00226     Diff8uC1(uchar _lo, uchar _up) : lo(_lo), interval(_lo + _up) {}
00227     bool operator()(const uchar* a, const uchar* b) const
00228     { return (unsigned)(a[0] - b[0] + lo) <= interval; }
00229     unsigned lo, interval;
00230 };
00231 
00232 struct Diff8uC3
00233 {
00234     Diff8uC3(Vec3b _lo, Vec3b _up)
00235     {
00236         for( int k = 0; k < 3; k++ )
00237             lo[k] = _lo[k], interval[k] = _lo[k] + _up[k];
00238     }
00239     bool operator()(const Vec3b* a, const Vec3b* b) const
00240     {
00241         return (unsigned)(a[0][0] - b[0][0] + lo[0]) <= interval[0] &&
00242                (unsigned)(a[0][1] - b[0][1] + lo[1]) <= interval[1] &&
00243                (unsigned)(a[0][2] - b[0][2] + lo[2]) <= interval[2];
00244     }
00245     unsigned lo[3], interval[3];
00246 };
00247 
00248 template<typename _Tp>
00249 struct DiffC1
00250 {
00251     DiffC1(_Tp _lo, _Tp _up) : lo(-_lo), up(_up) {}
00252     bool operator()(const _Tp* a, const _Tp* b) const
00253     {
00254         _Tp d = a[0] - b[0];
00255         return lo <= d && d <= up;
00256     }
00257     _Tp lo, up;
00258 };
00259 
00260 template<typename _Tp>
00261 struct DiffC3
00262 {
00263     DiffC3(_Tp _lo, _Tp _up) : lo(-_lo), up(_up) {}
00264     bool operator()(const _Tp* a, const _Tp* b) const
00265     {
00266         _Tp d = *a - *b;
00267         return lo[0] <= d[0] && d[0] <= up[0] &&
00268                lo[1] <= d[1] && d[1] <= up[1] &&
00269                lo[2] <= d[2] && d[2] <= up[2];
00270     }
00271     _Tp lo, up;
00272 };
00273 
00274 typedef DiffC1<int> Diff32sC1;
00275 typedef DiffC3<Vec3i> Diff32sC3;
00276 typedef DiffC1<float> Diff32fC1;
00277 typedef DiffC3<Vec3f> Diff32fC3;
00278 
00279 template<typename _Tp, typename _MTp, typename _WTp, class Diff>
00280 static void
00281 floodFillGrad_CnIR( Mat& image, Mat& msk,
00282                    Point seed, _Tp newVal, _MTp newMaskVal,
00283                    Diff diff, ConnectedComp* region, int flags,
00284                    std::vector<FFillSegment>* buffer )
00285 {
00286     int step = (int)image.step, maskStep = (int)msk.step;
00287     uchar* pImage = image.ptr();
00288     _Tp* img = (_Tp*)(pImage + step*seed.y);
00289     uchar* pMask = msk.ptr() + maskStep + sizeof(_MTp);
00290     _MTp* mask = (_MTp*)(pMask + maskStep*seed.y);
00291     int i, L, R;
00292     int area = 0;
00293     int XMin, XMax, YMin = seed.y, YMax = seed.y;
00294     int _8_connectivity = (flags & 255) == 8;
00295     int fixedRange = flags & FLOODFILL_FIXED_RANGE;
00296     int fillImage = (flags & FLOODFILL_MASK_ONLY) == 0;
00297     FFillSegment* buffer_end = &buffer->front() + buffer->size(), *head = &buffer->front(), *tail = &buffer->front();
00298 
00299     L = R = seed.x;
00300     if( mask[L] )
00301         return;
00302 
00303     mask[L] = newMaskVal;
00304     _Tp val0 = img[L];
00305 
00306     if( fixedRange )
00307     {
00308         while( !mask[R + 1] && diff( img + (R+1), &val0 ))
00309             mask[++R] = newMaskVal;
00310 
00311         while( !mask[L - 1] && diff( img + (L-1), &val0 ))
00312             mask[--L] = newMaskVal;
00313     }
00314     else
00315     {
00316         while( !mask[R + 1] && diff( img + (R+1), img + R ))
00317             mask[++R] = newMaskVal;
00318 
00319         while( !mask[L - 1] && diff( img + (L-1), img + L ))
00320             mask[--L] = newMaskVal;
00321     }
00322 
00323     XMax = R;
00324     XMin = L;
00325 
00326     ICV_PUSH( seed.y, L, R, R + 1, R, UP );
00327 
00328     while( head != tail )
00329     {
00330         int k, YC, PL, PR, dir;
00331         ICV_POP( YC, L, R, PL, PR, dir );
00332 
00333         int data[][3] =
00334         {
00335             {-dir, L - _8_connectivity, R + _8_connectivity},
00336             {dir, L - _8_connectivity, PL - 1},
00337             {dir, PR + 1, R + _8_connectivity}
00338         };
00339 
00340         unsigned length = (unsigned)(R-L);
00341 
00342         if( region )
00343         {
00344             area += (int)length + 1;
00345 
00346             if( XMax < R ) XMax = R;
00347             if( XMin > L ) XMin = L;
00348             if( YMax < YC ) YMax = YC;
00349             if( YMin > YC ) YMin = YC;
00350         }
00351 
00352         for( k = 0; k < 3; k++ )
00353         {
00354             dir = data[k][0];
00355             img = (_Tp*)(pImage + (YC + dir) * step);
00356             _Tp* img1 = (_Tp*)(pImage + YC * step);
00357             mask = (_MTp*)(pMask + (YC + dir) * maskStep);
00358             int left = data[k][1];
00359             int right = data[k][2];
00360 
00361             if( fixedRange )
00362                 for( i = left; i <= right; i++ )
00363                 {
00364                     if( !mask[i] && diff( img + i, &val0 ))
00365                     {
00366                         int j = i;
00367                         mask[i] = newMaskVal;
00368                         while( !mask[--j] && diff( img + j, &val0 ))
00369                             mask[j] = newMaskVal;
00370 
00371                         while( !mask[++i] && diff( img + i, &val0 ))
00372                             mask[i] = newMaskVal;
00373 
00374                         ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir );
00375                     }
00376                 }
00377             else if( !_8_connectivity )
00378                 for( i = left; i <= right; i++ )
00379                 {
00380                     if( !mask[i] && diff( img + i, img1 + i ))
00381                     {
00382                         int j = i;
00383                         mask[i] = newMaskVal;
00384                         while( !mask[--j] && diff( img + j, img + (j+1) ))
00385                             mask[j] = newMaskVal;
00386 
00387                         while( !mask[++i] &&
00388                               (diff( img + i, img + (i-1) ) ||
00389                                (diff( img + i, img1 + i) && i <= R)))
00390                             mask[i] = newMaskVal;
00391 
00392                         ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir );
00393                     }
00394                 }
00395             else
00396                 for( i = left; i <= right; i++ )
00397                 {
00398                     int idx;
00399                     _Tp val;
00400 
00401                     if( !mask[i] &&
00402                        (((val = img[i],
00403                           (unsigned)(idx = i-L-1) <= length) &&
00404                          diff( &val, img1 + (i-1))) ||
00405                         ((unsigned)(++idx) <= length &&
00406                          diff( &val, img1 + i )) ||
00407                         ((unsigned)(++idx) <= length &&
00408                          diff( &val, img1 + (i+1) ))))
00409                     {
00410                         int j = i;
00411                         mask[i] = newMaskVal;
00412                         while( !mask[--j] && diff( img + j, img + (j+1) ))
00413                             mask[j] = newMaskVal;
00414 
00415                         while( !mask[++i] &&
00416                               ((val = img[i],
00417                                 diff( &val, img + (i-1) )) ||
00418                                (((unsigned)(idx = i-L-1) <= length &&
00419                                  diff( &val, img1 + (i-1) ))) ||
00420                                ((unsigned)(++idx) <= length &&
00421                                 diff( &val, img1 + i )) ||
00422                                ((unsigned)(++idx) <= length &&
00423                                 diff( &val, img1 + (i+1) ))))
00424                             mask[i] = newMaskVal;
00425 
00426                         ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir );
00427                     }
00428                 }
00429         }
00430 
00431         img = (_Tp*)(pImage + YC * step);
00432         if( fillImage )
00433             for( i = L; i <= R; i++ )
00434                 img[i] = newVal;
00435         /*else if( region )
00436          for( i = L; i <= R; i++ )
00437          sum += img[i];*/
00438     }
00439 
00440     if( region )
00441     {
00442         region->pt = seed;
00443         region->label = saturate_cast<int>(newMaskVal);
00444         region->area = area;
00445         region->rect.x = XMin;
00446         region->rect.y = YMin;
00447         region->rect.width = XMax - XMin + 1;
00448         region->rect.height = YMax - YMin + 1;
00449     }
00450 }
00451 
00452 }
00453 
00454 /****************************************************************************************\
00455 *                                    External Functions                                  *
00456 \****************************************************************************************/
00457 
00458 int cv::floodFill( InputOutputArray _image, InputOutputArray _mask,
00459                   Point seedPoint, Scalar newVal, Rect* rect,
00460                   Scalar loDiff, Scalar upDiff, int flags )
00461 {
00462     ConnectedComp comp;
00463     std::vector<FFillSegment> buffer;
00464 
00465     if( rect )
00466         *rect = Rect();
00467 
00468     int i, connectivity = flags & 255;
00469     union {
00470         uchar b[4];
00471         int i[4];
00472         float f[4];
00473         double _[4];
00474     } nv_buf;
00475     nv_buf._[0] = nv_buf._[1] = nv_buf._[2] = nv_buf._[3] = 0;
00476 
00477     struct { Vec3b b; Vec3i i; Vec3f f; } ld_buf, ud_buf;
00478     Mat img = _image.getMat(), mask;
00479     if( !_mask.empty() )
00480         mask = _mask.getMat();
00481     Size size = img.size();
00482 
00483     int type = img.type();
00484     int depth = img.depth();
00485     int cn = img.channels();
00486 
00487     if ( (cn != 1) && (cn != 3) )
00488     {
00489         CV_Error( CV_StsBadArg, "Number of channels in input image must be 1 or 3" );
00490     }
00491 
00492     if( connectivity == 0 )
00493         connectivity = 4;
00494     else if( connectivity != 4 && connectivity != 8 )
00495         CV_Error( CV_StsBadFlag, "Connectivity must be 4, 0(=4) or 8" );
00496 
00497     bool is_simple = mask.empty() && (flags & FLOODFILL_MASK_ONLY) == 0;
00498 
00499     for( i = 0; i < cn; i++ )
00500     {
00501         if( loDiff[i] < 0 || upDiff[i] < 0 )
00502             CV_Error( CV_StsBadArg, "lo_diff and up_diff must be non-negative" );
00503         is_simple = is_simple && fabs(loDiff[i]) < DBL_EPSILON && fabs(upDiff[i]) < DBL_EPSILON;
00504     }
00505 
00506     if( (unsigned)seedPoint.x >= (unsigned)size.width ||
00507        (unsigned)seedPoint.y >= (unsigned)size.height )
00508         CV_Error( CV_StsOutOfRange, "Seed point is outside of image" );
00509 
00510     scalarToRawData( newVal, &nv_buf, type, 0);
00511     size_t buffer_size = MAX( size.width, size.height ) * 2;
00512     buffer.resize( buffer_size );
00513 
00514     if( is_simple )
00515     {
00516         size_t elem_size = img.elemSize();
00517         const uchar* seed_ptr = img.ptr(seedPoint.y) + elem_size*seedPoint.x;
00518 
00519         size_t k = 0;
00520         for(; k < elem_size; k++)
00521             if (seed_ptr[k] != nv_buf.b[k])
00522                 break;
00523 
00524         if( k != elem_size )
00525         {
00526             if( type == CV_8UC1 )
00527                 floodFill_CnIR(img, seedPoint, nv_buf.b[0], &comp, flags, &buffer);
00528             else if( type == CV_8UC3 )
00529                 floodFill_CnIR(img, seedPoint, Vec3b(nv_buf.b), &comp, flags, &buffer);
00530             else if( type == CV_32SC1 )
00531                 floodFill_CnIR(img, seedPoint, nv_buf.i[0], &comp, flags, &buffer);
00532             else if( type == CV_32FC1 )
00533                 floodFill_CnIR(img, seedPoint, nv_buf.f[0], &comp, flags, &buffer);
00534             else if( type == CV_32SC3 )
00535                 floodFill_CnIR(img, seedPoint, Vec3i(nv_buf.i), &comp, flags, &buffer);
00536             else if( type == CV_32FC3 )
00537                 floodFill_CnIR(img, seedPoint, Vec3f(nv_buf.f), &comp, flags, &buffer);
00538             else
00539                 CV_Error( CV_StsUnsupportedFormat, "" );
00540             if( rect )
00541                 *rect = comp.rect;
00542             return comp.area;
00543         }
00544     }
00545 
00546     if( mask.empty() )
00547     {
00548         Mat tempMask( size.height + 2, size.width + 2, CV_8UC1 );
00549         tempMask.setTo(Scalar::all(0));
00550         mask = tempMask;
00551     }
00552     else
00553     {
00554         CV_Assert( mask.rows == size.height+2 && mask.cols == size.width+2 );
00555         CV_Assert( mask.type() == CV_8U );
00556     }
00557 
00558     memset( mask.ptr(), 1, mask.cols );
00559     memset( mask.ptr(mask.rows-1), 1, mask.cols );
00560 
00561     for( i = 1; i <= size.height; i++ )
00562     {
00563         mask.at<uchar>(i, 0) = mask.at<uchar>(i, mask.cols-1) = (uchar)1;
00564     }
00565 
00566     if( depth == CV_8U )
00567         for( i = 0; i < cn; i++ )
00568         {
00569             ld_buf.b[i] = saturate_cast<uchar>(cvFloor(loDiff[i]));
00570             ud_buf.b[i] = saturate_cast<uchar>(cvFloor(upDiff[i]));
00571         }
00572     else if( depth == CV_32S )
00573         for( i = 0; i < cn; i++ )
00574         {
00575             ld_buf.i[i] = cvFloor(loDiff[i]);
00576             ud_buf.i[i] = cvFloor(upDiff[i]);
00577         }
00578     else if( depth == CV_32F )
00579         for( i = 0; i < cn; i++ )
00580         {
00581             ld_buf.f[i] = (float)loDiff[i];
00582             ud_buf.f[i] = (float)upDiff[i];
00583         }
00584     else
00585         CV_Error( CV_StsUnsupportedFormat, "" );
00586 
00587     uchar newMaskVal = (uchar)((flags & ~0xff) == 0 ? 1 : ((flags >> 8) & 255));
00588 
00589     if( type == CV_8UC1 )
00590         floodFillGrad_CnIR<uchar, uchar, int, Diff8uC1>(
00591                 img, mask, seedPoint, nv_buf.b[0], newMaskVal,
00592                 Diff8uC1(ld_buf.b[0], ud_buf.b[0]),
00593                 &comp, flags, &buffer);
00594     else if( type == CV_8UC3 )
00595         floodFillGrad_CnIR<Vec3b, uchar, Vec3i, Diff8uC3>(
00596                 img, mask, seedPoint, Vec3b(nv_buf.b), newMaskVal,
00597                 Diff8uC3(ld_buf.b, ud_buf.b),
00598                 &comp, flags, &buffer);
00599     else if( type == CV_32SC1 )
00600         floodFillGrad_CnIR<int, uchar, int, Diff32sC1>(
00601                 img, mask, seedPoint, nv_buf.i[0], newMaskVal,
00602                 Diff32sC1(ld_buf.i[0], ud_buf.i[0]),
00603                 &comp, flags, &buffer);
00604     else if( type == CV_32SC3 )
00605         floodFillGrad_CnIR<Vec3i, uchar, Vec3i, Diff32sC3>(
00606                 img, mask, seedPoint, Vec3i(nv_buf.i), newMaskVal,
00607                 Diff32sC3(ld_buf.i, ud_buf.i),
00608                 &comp, flags, &buffer);
00609     else if( type == CV_32FC1 )
00610         floodFillGrad_CnIR<float, uchar, float, Diff32fC1>(
00611                 img, mask, seedPoint, nv_buf.f[0], newMaskVal,
00612                 Diff32fC1(ld_buf.f[0], ud_buf.f[0]),
00613                 &comp, flags, &buffer);
00614     else if( type == CV_32FC3 )
00615         floodFillGrad_CnIR<Vec3f, uchar, Vec3f, Diff32fC3>(
00616                 img, mask, seedPoint, Vec3f(nv_buf.f), newMaskVal,
00617                 Diff32fC3(ld_buf.f, ud_buf.f),
00618                 &comp, flags, &buffer);
00619     else
00620         CV_Error(CV_StsUnsupportedFormat, "");
00621 
00622     if( rect )
00623         *rect = comp.rect;
00624     return comp.area;
00625 }
00626 
00627 
00628 int cv::floodFill( InputOutputArray _image, Point seedPoint,
00629                   Scalar newVal, Rect* rect,
00630                   Scalar loDiff, Scalar upDiff, int flags )
00631 {
00632     return floodFill(_image, Mat(), seedPoint, newVal, rect, loDiff, upDiff, flags);
00633 }
00634 
00635 
00636 CV_IMPL void
00637 cvFloodFill( CvArr* arr, CvPoint seed_point,
00638              CvScalar  newVal, CvScalar  lo_diff, CvScalar  up_diff,
00639              CvConnectedComp* comp, int flags, CvArr* maskarr )
00640 {
00641     if( comp )
00642         memset( comp, 0, sizeof(*comp) );
00643 
00644     cv::Mat img = cv::cvarrToMat(arr), mask = cv::cvarrToMat(maskarr);
00645     int area = cv::floodFill(img, mask, seed_point, newVal,
00646                              comp ? (cv::Rect*)&comp->rect : 0,
00647                              lo_diff, up_diff, flags );
00648     if( comp )
00649     {
00650         comp->area = area;
00651         comp->value = newVal;
00652     }
00653 }
00654 
00655 /* End of file. */
00656