16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cv.h"
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct _CvRGBf
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{   float blue;
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float green;
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float red;
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn_CvRGBf;
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct _CvRect16u
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ushort x1, y1, x2, y2;
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn_CvRect16u;
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct _CvPyramid
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float c;
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    struct _CvPyramid *p;
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int a;
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvRect16u rect;      /*  ROI for the connected component    */
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} _CvPyramid;
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* element of base layer */
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct _CvPyramidBase
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float c;
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    struct _CvPyramid *p;
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn_CvPyramidBase;
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct _CvPyramidC3
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvRGBf c;
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    struct _CvPyramidC3 *p;
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int a;
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvRect16u rect;      /*  ROI for the connected component    */
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} _CvPyramidC3;
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* element of base layer */
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct _CvPyramidBaseC3
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvRGBf c;
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    struct _CvPyramidC3 *p;
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn_CvPyramidBaseC3;
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct _CvListNode
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    struct _CvListNode* next;
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* data;
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn_CvListNode;
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus  icvSegmentClusterC1( CvSeq* cmp_seq, CvSeq* res_seq,
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 double threshold,
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 _CvPyramid* first_level_end,
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 CvSize first_level_size );
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus  icvSegmentClusterC3( CvSeq* cmp_seq, CvSeq* res_seq,
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 double threshold,
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 _CvPyramidC3* first_level_end,
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 CvSize first_level_size );
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus icvUpdatePyrLinks_8u_C1
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (int layer, void *layer_data, CvSize size, void *parent_layer,
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn     void *_writer, float threshold, int is_last_iter, void *_stub, CvWriteNodeFunction /*func*/);
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus icvUpdatePyrLinks_8u_C3
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (int layer, void *layer_data, CvSize size, void *parent_layer,
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn     void *_writer, float threshold, int is_last_iter, void *_stub, CvWriteNodeFunction /*func*/);
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvMaxRoi( _CvRect16u *max_rect, _CvRect16u* cur_rect );
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvMaxRoi1( _CvRect16u *max_rect, int x, int y );
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_CHECK( icvFun )                                             \
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  {                                                                     \
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( icvFun != CV_OK )                                               \
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn     goto M_END;                                                        \
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_MAX3( a, b, c) ((a)>(b) ? ((a)>(c) ? (a) : (c)) : ((b)>(c) ? (b) : (c)))
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*#define _CV_RGB_DIST(a, b)  _CV_MAX3((float)fabs((a).red - (b).red),      \
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       (float)fabs((a).green - (b).green),  \
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       (float)fabs((a).blue - (b).blue))*/
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_NEXT_BASE_C1(p,n) (_CvPyramid*)((char*)(p) + (n)*sizeof(_CvPyramidBase))
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_NEXT_BASE_C3(p,n) (_CvPyramidC3*)((char*)(p) + (n)*sizeof(_CvPyramidBaseC3))
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_INLINE float icvRGBDist_Max( const _CvRGBf& a, const _CvRGBf& b )
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float tr = (float)fabs(a.red - b.red);
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float tg = (float)fabs(a.green - b.green);
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float tb = (float)fabs(a.blue - b.blue);
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return _CV_MAX3( tr, tg, tb );
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_INLINE float icvRGBDist_Sum( const _CvRGBf& a, const _CvRGBf& b )
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float tr = (float)fabs(a.red - b.red);
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float tg = (float)fabs(a.green - b.green);
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float tb = (float)fabs(a.blue - b.blue);
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return (tr + tg + tb);
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 1
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_RGB_DIST  icvRGBDist_Max
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_RGB_THRESH_SCALE   1
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_RGB_DIST  icvRGBDist_Sum
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_RGB_THRESH_SCALE   3
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_INV_TAB_SIZE   32
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const float icvInvTab[ /*_CV_INV_TAB_SIZE*/ ] =
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    1.00000000f, 0.50000000f, 0.33333333f, 0.25000000f, 0.20000000f, 0.16666667f,
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.14285714f, 0.12500000f, 0.11111111f, 0.10000000f, 0.09090909f, 0.08333333f,
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.07692308f, 0.07142857f, 0.06666667f, 0.06250000f, 0.05882353f, 0.05555556f,
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.05263158f, 0.05000000f, 0.04761905f, 0.04545455f, 0.04347826f, 0.04166667f,
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.04000000f, 0.03846154f, 0.03703704f, 0.03571429f, 0.03448276f, 0.03333333f,
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.03225806f, 0.03125000f
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWritePyrNode( void *elem, void *writer )
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_WRITE_SEQ_ELEM( *(_CvListNode *) elem, *(CvSeqWriter *) writer );
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrSegmentation8uC1R( uchar * src_image, int src_step,
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         uchar * dst_image, int dst_step,
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         CvSize roi, CvFilter filter,
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         CvSeq ** dst_comp, CvMemStorage * storage,
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         int level, int threshold1, int threshold2 )
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, l;
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int step;
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int max_iter = 3;     /* maximum number of iterations */
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cur_iter = 0;           /* current iteration */
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramid *pyram[16];      /* pointers to the pyramid down up to level */
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *pyramida = 0;
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramid stub;
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramid *p_cur;
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidBase *p_base;
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvListNode cmp_node;
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeq *cmp_seq = 0;
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeq *res_seq = 0;
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMemStorage *temp_storage = 0;
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size;
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvStatus status;
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqWriter writer;
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int buffer_size;
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    char *buffer = 0;
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    status = CV_OK;
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* clear pointer to resultant sequence */
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst_comp )
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *dst_comp = 0;
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* check args */
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !src_image || !dst_image || !storage || !dst_comp )
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( roi.width <= 0 || roi.height <= 0 || src_step < roi.width || dst_step < roi.width )
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( filter != CV_GAUSSIAN_5x5 )
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( threshold1 < 0 || threshold2 < 0 )
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( level <= 0 )
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ((roi.width | roi.height) & ((1 << level) - 1)) != 0 )
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADCOEF_ERR;
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    temp_storage = cvCreateChildMemStorage( storage );
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* sequence for temporary components */
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cmp_seq = cvCreateSeq( 0, sizeof( CvSeq ), sizeof( _CvListNode ), temp_storage );
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( cmp_seq != 0 );
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    res_seq = cvCreateSeq( CV_SEQ_CONNECTED_COMP, sizeof( CvSeq ),
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           sizeof( CvConnectedComp ), storage );
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( res_seq != 0 );
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* calculate buffer size */
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buffer_size = roi.width * roi.height * (sizeof( float ) + sizeof( _CvPyramidBase ));
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( l = 1; l <= level; l++ )
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer_size += ((roi.width >> l) + 1) * ((roi.height >> l) + 1) * sizeof(_CvPyramid);
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* allocate buffer */
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buffer = (char *) cvAlloc( buffer_size );
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !buffer )
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = CV_OUTOFMEM_ERR;
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto M_END;
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pyramida = (float *) buffer;
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* initialization pyramid-linking properties down up to level */
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    step = roi.width * sizeof( float );
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat _src;
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat _pyramida;
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvInitMatHeader( &_src, roi.height, roi.width, CV_8UC1, src_image, src_step );
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvInitMatHeader( &_pyramida, roi.height, roi.width, CV_32FC1, pyramida, step );
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvConvert( &_src, &_pyramida );
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /*_CV_CHECK( icvCvtTo_32f_C1R( src_image, src_step, pyramida, step, roi, CV_8UC1 ));*/
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p_base = (_CvPyramidBase *) (buffer + step * roi.height);
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pyram[0] = (_CvPyramid *) p_base;
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* fill base level of pyramid */
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < roi.height; i++ )
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < roi.width; j++, p_base++ )
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_base->c = pyramida[i * roi.width + j];
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_base->p = &stub;
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p_cur = (_CvPyramid *) p_base;
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size = roi;
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* calculate initial pyramid */
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( l = 1; l <= level; l++ )
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSize dst_size = { size.width/2+1, size.height/2+1 };
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat prev_level = cvMat( size.height, size.width, CV_32FC1 );
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat next_level = cvMat( dst_size.height, dst_size.width, CV_32FC1 );
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvSetData( &prev_level, pyramida, step );
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvSetData( &next_level, pyramida, step );
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvPyrDown( &prev_level, &next_level );
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //_CV_CHECK( icvPyrDown_Gauss5x5_32f_C1R( pyramida, step, pyramida, step, size, buff ));
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //_CV_CHECK( icvPyrDownBorder_32f_CnR( pyramida, step, size, pyramida, step, dst_size, 1 ));
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pyram[l] = p_cur;
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.width = dst_size.width - 1;
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.height = dst_size.height - 1;
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* fill layer #l */
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= size.height; i++ )
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j <= size.width; j++, p_cur++ )
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->c = pyramida[i * roi.width + j];
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->p = &stub;
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->a = 0;
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->rect.x2 = 0;
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartAppendToSeq( cmp_seq, &writer );
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* do several iterations to determine son-father links */
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( cur_iter = 0; cur_iter < max_iter; cur_iter++ )
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int is_last_iter = cur_iter == max_iter - 1;
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size = roi;
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* build son-father links down up to level */
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( l = 0; l < level; l++ )
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvUpdatePyrLinks_8u_C1( l, pyram[l], size, pyram[l + 1], &writer,
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      (float) threshold1, is_last_iter, &stub,
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      icvWritePyrNode );
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* clear last border row */
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( l > 0 )
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur = pyram[l] + (size.width + 1) * size.height;
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j <= size.width; j++ )
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur[j].c = 0;
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.width >>= 1;
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.height >>= 1;
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  clear the old c value for the last level     */
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p_cur = pyram[level];
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= size.height; i++, p_cur += size.width + 1 )
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j <= size.width; j++ )
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur[j].c = 0;
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size = roi;
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        step = roi.width;
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* calculate average c value for the 0 < l <=level   */
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( l = 0; l < level; l++, step = (step >> 1) + 1 )
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvPyramid *p_prev, *p_row_prev;
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            stub.c = 0;
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* calculate average c value for the next level   */
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( l == 0 )
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_base = (_CvPyramidBase *) pyram[0];
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i < roi.height; i++, p_base += size.width )
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j < size.width; j += 2 )
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        _CvPyramid *p1 = p_base[j].p;
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        _CvPyramid *p2 = p_base[j + 1].p;
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p1->c += p_base[j].c;
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p2->c += p_base[j + 1].c;
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur = pyram[l];
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i < size.height; i++, p_cur += size.width + 1 )
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j < size.width; j += 2 )
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        _CvPyramid *p1 = p_cur[j].p;
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        _CvPyramid *p2 = p_cur[j + 1].p;
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        float t0 = (float) p_cur[j].a * p_cur[j].c;
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        float t1 = (float) p_cur[j + 1].a * p_cur[j + 1].c;
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p1->c += t0;
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p2->c += t1;
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( !is_last_iter )
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].a = p_cur[j + 1].a = 0;
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( !is_last_iter )
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[size.width].a = 0;
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !is_last_iter )
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j <= size.width; j++ )
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[j].a = 0;
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* assign random values of the next level null c   */
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_cur = pyram[l + 1];
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_row_prev = p_prev = pyram[l];
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.width >>= 1;
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.height >>= 1;
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i <= size.height; i++, p_cur += size.width + 1 )
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( i < size.height || !is_last_iter )
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j < size.width; j++ )
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int a = p_cur[j].a;
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( a != 0 )
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            if( a <= _CV_INV_TAB_SIZE )
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                p_cur[j].c *= icvInvTab[a - 1];
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            else
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                p_cur[j].c /= a;
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        else
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].c = p_prev->c;
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( l == 0 )
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_prev = _CV_NEXT_BASE_C1(p_prev,2);
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        else
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_prev += 2;
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( p_cur[size.width].a == 0 )
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[size.width].c = p_prev[(l != 0) - 1].c;
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[size.width].c /= p_cur[size.width].a;
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( is_last_iter )
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cmp_node.data = p_cur + size.width;
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CV_WRITE_SEQ_ELEM( cmp_node, writer );
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j <= size.width; j++ )
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int a = p_cur[j].a;
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( a != 0 )
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            if( a <= _CV_INV_TAB_SIZE )
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                p_cur[j].c *= icvInvTab[a - 1];
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            else
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                p_cur[j].c /= a;
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cmp_node.data = p_cur + j;
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CV_WRITE_SEQ_ELEM( cmp_node, writer );
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        else
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].c = p_prev->c;
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( l == 0 )
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_prev = _CV_NEXT_BASE_C1(p_prev, (j * 2 < step - 2 ? 2 : 1));
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        else
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_prev++;
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( l + 1 == level && !is_last_iter )
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j <= size.width; j++ )
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[j].a = 0;
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !(i & 1) )
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_prev = p_row_prev;
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_prev = (_CvPyramid*)((char*)p_row_prev + step *
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        (l == 0 ? sizeof(_CvPyramidBase) : sizeof(_CvPyramid)));
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                           /*  end of the iteration process  */
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* construct a connected  components   */
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size.width = roi.width >> level;
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size.height = roi.height >> level;
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p_cur = pyram[level];
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < size.height; i++, p_cur += size.width + 1 )
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < size.width; j++ )
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( p_cur[j].a != 0 )
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cmp_node.data = p_cur + j;
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_WRITE_SEQ_ELEM( cmp_node, writer );
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvEndWriteSeq( &writer );
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* clusterization segmented components and construction
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   output connected components                            */
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvSegmentClusterC1( cmp_seq, res_seq, threshold2, pyram[1], roi );
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* convert (inplace) resultant segment values to int (top level) */
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* propagate segment values top down */
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( l = level - 1; l >= 0; l-- )
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p_cur = pyram[l];
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.width <<= 1;
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.height <<= 1;
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( l == 0 )
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.width--;
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.height--;
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= size.height; i++ )
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j <= size.width; j++ )
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _CvPyramid *p = p_cur->p;
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                assert( p != 0 );
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( p != &stub )
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur->c = p->c;
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( l == 0 )
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    Cv32suf _c;
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* copy the segmented values to destination image */
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    _c.f = p_cur->c; dst_image[j] = (uchar)_c.i;
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur = _CV_NEXT_BASE_C1(p_cur, 1);
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur++;
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( l == 0 )
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst_image += dst_step;
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  M_END:
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &buffer );
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMemStorage( &temp_storage );
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( status == CV_OK )
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *dst_comp = res_seq;
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return status;
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    color!!!  image segmentation by pyramid-linking
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrSegmentation8uC3R( uchar * src_image, int src_step,
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         uchar * dst_image, int dst_step,
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         CvSize roi, CvFilter filter,
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         CvSeq ** dst_comp, CvMemStorage * storage,
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         int level, int threshold1, int threshold2 )
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, l;
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int step;
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int max_iter = 3;     /* maximum number of iterations */
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cur_iter = 0;           /* current iteration */
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidC3 *pyram[16];    /* pointers to the pyramid down up to level */
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *pyramida = 0;
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidC3 stub;
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidC3 *p_cur;
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidBaseC3 *p_base;
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvListNode cmp_node;
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeq *cmp_seq = 0;
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeq *res_seq = 0;
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMemStorage *temp_storage = 0;
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size;
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvStatus status;
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqWriter writer;
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int buffer_size;
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    char *buffer = 0;
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    status = CV_OK;
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    threshold1 *= _CV_RGB_THRESH_SCALE;
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    threshold2 *= _CV_RGB_THRESH_SCALE;
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* clear pointer to resultant sequence */
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst_comp )
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *dst_comp = 0;
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* check args */
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !src_image || !dst_image || !storage || !dst_comp )
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( roi.width <= 0 || roi.height <= 0 ||
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src_step < roi.width * 3 || dst_step < roi.width * 3 ) return CV_BADSIZE_ERR;
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( filter != CV_GAUSSIAN_5x5 )
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( threshold1 < 0 || threshold2 < 0 )
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( level <= 0 )
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ((roi.width | roi.height) & ((1 << level) - 1)) != 0 )
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADCOEF_ERR;
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    temp_storage = cvCreateChildMemStorage( storage );
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* sequence for temporary components */
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cmp_seq = cvCreateSeq( 0, sizeof( CvSeq ), sizeof( _CvListNode ), temp_storage );
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( cmp_seq != 0 );
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    res_seq = cvCreateSeq( CV_SEQ_CONNECTED_COMP, sizeof( CvSeq ),
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           sizeof( CvConnectedComp ), storage );
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( res_seq != 0 );
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* calculate buffer size */
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buffer_size = roi.width * roi.height * (sizeof( _CvRGBf ) + sizeof( _CvPyramidBaseC3 ));
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( l = 1; l <= level; l++ )
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer_size += ((roi.width >> l) + 1) * ((roi.height >> l) + 1) * sizeof(_CvPyramidC3);
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* allocate buffer */
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buffer = (char *) cvAlloc( buffer_size );
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !buffer )
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = CV_OUTOFMEM_ERR;
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto M_END;
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pyramida = (float *) buffer;
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* initialization pyramid-linking properties down up to level */
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    step = roi.width * sizeof( _CvRGBf );
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat _src;
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat _pyramida;
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvInitMatHeader( &_src, roi.height, roi.width, CV_8UC3, src_image, src_step );
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvInitMatHeader( &_pyramida, roi.height, roi.width, CV_32FC3, pyramida, step );
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvConvert( &_src, &_pyramida );
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /*_CV_CHECK( icvCvtTo_32f_C1R( src_image, src_step, pyramida, step,
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 cvSize( roi.width * 3, roi.height ), CV_8UC1 ));*/
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p_base = (_CvPyramidBaseC3 *) (buffer + step * roi.height);
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pyram[0] = (_CvPyramidC3 *) p_base;
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* fill base level of pyramid */
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < roi.height; i++ )
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < roi.width; j++, p_base++ )
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_base->c = ((_CvRGBf *) pyramida)[i * roi.width + j];
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_base->p = &stub;
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p_cur = (_CvPyramidC3 *) p_base;
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size = roi;
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* calculate initial pyramid */
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( l = 1; l <= level; l++ )
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSize dst_size = { size.width/2 + 1, size.height/2 + 1 };
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat prev_level = cvMat( size.height, size.width, CV_32FC3 );
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat next_level = cvMat( dst_size.height, dst_size.width, CV_32FC3 );
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvSetData( &prev_level, pyramida, step );
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvSetData( &next_level, pyramida, step );
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvPyrDown( &prev_level, &next_level );
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //_CV_CHECK( icvPyrDown_Gauss5x5_32f_C3R( pyramida, step, pyramida, step, size, buff ));
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //_CV_CHECK( icvPyrDownBorder_32f_CnR( pyramida, step, size, pyramida, step, dst_size, 3 ));
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pyram[l] = p_cur;
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.width = dst_size.width - 1;
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.height = dst_size.height - 1;
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* fill layer #l */
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= size.height; i++ )
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( (char*)p_cur - buffer < buffer_size );
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j <= size.width; j++, p_cur++ )
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->c = ((_CvRGBf *) pyramida)[i * roi.width + j];
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->p = &stub;
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->a = 0;
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->rect.x2 = 0;
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartAppendToSeq( cmp_seq, &writer );
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* do several iterations to determine son-father links */
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( cur_iter = 0; cur_iter < max_iter; cur_iter++ )
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int is_last_iter = cur_iter == max_iter - 1;
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size = roi;
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* build son-father links down up to level */
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( l = 0; l < level; l++ )
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvUpdatePyrLinks_8u_C3( l, pyram[l], size, pyram[l + 1], &writer,
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      (float) threshold1, is_last_iter, &stub,
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      icvWritePyrNode );
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* clear last border row */
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( l > 0 )
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur = pyram[l] + (size.width + 1) * size.height;
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j <= size.width; j++ )
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur[j].c.blue = p_cur[j].c.green = p_cur[j].c.red = 0;
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.width >>= 1;
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.height >>= 1;
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*  clear the old c value for the last level     */
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p_cur = pyram[level];
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= size.height; i++, p_cur += size.width + 1 )
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j <= size.width; j++ )
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur[j].c.blue = p_cur[j].c.green = p_cur[j].c.red = 0;
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size = roi;
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        step = roi.width;
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* calculate average c value for the 0 < l <=level   */
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( l = 0; l < level; l++, step = (step >> 1) + 1 )
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvPyramidC3 *p_prev, *p_row_prev;
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            stub.c.blue = stub.c.green = stub.c.red = 0;
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* calculate average c value for the next level   */
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( l == 0 )
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_base = (_CvPyramidBaseC3 *) pyram[0];
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i < roi.height; i++, p_base += size.width )
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j < size.width; j++ )
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        _CvPyramidC3 *p = p_base[j].p;
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p->c.blue += p_base[j].c.blue;
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p->c.green += p_base[j].c.green;
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p->c.red += p_base[j].c.red;
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur = pyram[l];
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i < size.height; i++, p_cur += size.width + 1 )
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j < size.width; j++ )
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        _CvPyramidC3 *p = p_cur[j].p;
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        float a = (float) p_cur[j].a;
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p->c.blue += a * p_cur[j].c.blue;
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p->c.green += a * p_cur[j].c.green;
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p->c.red += a * p_cur[j].c.red;
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( !is_last_iter )
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].a = 0;
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( !is_last_iter )
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[size.width].a = 0;
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !is_last_iter )
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j <= size.width; j++ )
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[j].a = 0;
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* assign random values of the next level null c   */
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_cur = pyram[l + 1];
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_row_prev = p_prev = pyram[l];
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.width >>= 1;
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.height >>= 1;
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i <= size.height; i++, p_cur += size.width + 1 )
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( i < size.height || !is_last_iter )
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j < size.width; j++ )
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int a = p_cur[j].a;
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( a != 0 )
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            float inv_a;
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            if( a <= _CV_INV_TAB_SIZE )
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                inv_a = icvInvTab[a - 1];
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            else
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                inv_a = 1.f / a;
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].c.blue *= inv_a;
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].c.green *= inv_a;
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].c.red *= inv_a;
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        else
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].c = p_prev->c;
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( l == 0 )
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_prev = _CV_NEXT_BASE_C3( p_prev, 2 );
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        else
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_prev += 2;
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( p_cur[size.width].a == 0 )
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[size.width].c = p_prev[(l != 0) - 1].c;
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[size.width].c.blue /= p_cur[size.width].a;
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[size.width].c.green /= p_cur[size.width].a;
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[size.width].c.red /= p_cur[size.width].a;
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( is_last_iter )
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cmp_node.data = p_cur + size.width;
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CV_WRITE_SEQ_ELEM( cmp_node, writer );
8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j <= size.width; j++ )
8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int a = p_cur[j].a;
8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( a != 0 )
8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            float inv_a;
8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            if( a <= _CV_INV_TAB_SIZE )
8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                inv_a = icvInvTab[a - 1];
8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            else
8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                inv_a = 1.f / a;
9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].c.blue *= inv_a;
9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].c.green *= inv_a;
9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].c.red *= inv_a;
9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cmp_node.data = p_cur + j;
9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CV_WRITE_SEQ_ELEM( cmp_node, writer );
9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        else
9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_cur[j].c = p_prev->c;
9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( l == 0 )
9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_prev = _CV_NEXT_BASE_C3( p_prev, (j * 2 < step - 2 ? 2 : 1));
9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        else
9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            p_prev++;
9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( l + 1 == level && !is_last_iter )
9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 0; j <= size.width; j++ )
9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p_cur[j].a = 0;
9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !(i & 1) )
9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_prev = p_row_prev;
9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_prev = (_CvPyramidC3*)((char*)p_row_prev + step *
9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        (l == 0 ? sizeof( _CvPyramidBaseC3 ) : sizeof( _CvPyramidC3 )));
9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                           /*  end of the iteration process  */
9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* construct a connected  components   */
9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size.width = roi.width >> level;
9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size.height = roi.height >> level;
9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p_cur = pyram[level];
9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < size.height; i++, p_cur += size.width + 1 )
9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < size.width; j++ )
9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( p_cur[j].a != 0 )
9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cmp_node.data = p_cur + j;
9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_WRITE_SEQ_ELEM( cmp_node, writer );
9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvEndWriteSeq( &writer );
9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* clusterization segmented components and construction
9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   output connected components                            */
9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvSegmentClusterC3( cmp_seq, res_seq, threshold2, pyram[1], roi );
9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* convert (inplace) resultant segment values to int (top level) */
9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* propagate segment values top down */
9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( l = level - 1; l >= 0; l-- )
9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p_cur = pyram[l];
9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.width <<= 1;
9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.height <<= 1;
9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( l == 0 )
9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.width--;
9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size.height--;
9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= size.height; i++ )
9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j <= size.width; j++ )
9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _CvPyramidC3 *p = p_cur->p;
9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                assert( p != 0 );
9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( p != &stub )
9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur->c = p->c;
9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( l == 0 )
9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    Cv32suf _c;
9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* copy the segmented values to destination image */
9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    _c.f = p_cur->c.blue; dst_image[j*3] = (uchar)_c.i;
9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    _c.f = p_cur->c.green; dst_image[j*3+1] = (uchar)_c.i;
9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    _c.f = p_cur->c.red; dst_image[j*3+2] = (uchar)_c.i;
10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur = _CV_NEXT_BASE_C3(p_cur,1);
10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur++;
10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( l == 0 )
10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst_image += dst_step;
10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  M_END:
10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &buffer );
10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMemStorage( &temp_storage );
10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( status == CV_OK )
10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *dst_comp = res_seq;
10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return status;
10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus icvUpdatePyrLinks_8u_C1
10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (int layer, void *layer_data, CvSize size, void *parent_layer,
10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn     void *_writer, float threshold, int is_last_iter, void *_stub, CvWriteNodeFunction /*func*/)
10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j;
10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvListNode cmp_node;
10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramid *stub = (_CvPyramid *) _stub;
10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramid *p_cur = (_CvPyramid *) layer_data;
10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramid *p_next1 = (_CvPyramid *) parent_layer;
10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramid *p_next3 = p_next1 + (size.width >> 1) + 1;
10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqWriter & writer = *(CvSeqWriter *) _writer;
10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < size.height; i++ )
10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < size.width; j += 2 )
10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float c0, c1, c2, c3, c4;
10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvPyramid *p;
10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* son-father threshold linking for the current node establish */
10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c0 = p_cur->c;
10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* find pointer for the first pixel */
10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c1 = (float) fabs( c0 - p_next1[0].c );
10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c2 = (float) fabs( c0 - p_next1[1].c );
10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c3 = (float) fabs( c0 - p_next3[0].c );
10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c4 = (float) fabs( c0 - p_next3[1].c );
10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p = p_next1;
10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c2 )
10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next1 + 1;
10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c2;
10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c3 )
10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next3;
10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c3;
10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c4 )
10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next3 + 1;
10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c4;
10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 <= threshold )
10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->p = p;
10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( layer == 0 )
10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p->a++;
10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur = (_CvPyramid*)((char*)p_cur + sizeof(_CvPyramidBase));
10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( is_last_iter )
10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvMaxRoi1( &(p->rect), j, i );
10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int a = p_cur->a;
10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p->a += a;
10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur->c = 0;
10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur++;
10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( is_last_iter && a != 0 )
10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvMaxRoi( &(p->rect), &(p_cur[-1].rect) );
10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->p = stub;
10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( is_last_iter )
10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cmp_node.data = p_cur;
11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_WRITE_SEQ_ELEM( cmp_node, writer );
11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( layer == 0 )
11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur = _CV_NEXT_BASE_C1(p_cur,1);
11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur->c = 0;
11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur++;
11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* find pointer for the second pixel */
11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c0 = p_cur->c;
11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c1 = (float) fabs( c0 - p_next1[0].c );
11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c2 = (float) fabs( c0 - p_next1[1].c );
11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c3 = (float) fabs( c0 - p_next3[0].c );
11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c4 = (float) fabs( c0 - p_next3[1].c );
11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p = p_next1;
11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next1++;
11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c2 )
11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next1;
11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c2;
11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c3 )
11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next3;
11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c3;
11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next3++;
11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c4 )
11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next3;
11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c4;
11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 <= threshold )
11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->p = p;
11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( layer == 0 )
11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p->a++;
11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur = _CV_NEXT_BASE_C1(p_cur,1);
11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( is_last_iter )
11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvMaxRoi1( &(p->rect), j + 1, i );
11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int a = p_cur->a;
11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p->a += a;
11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur->c = 0;
11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur++;
11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( is_last_iter && a != 0 )
11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvMaxRoi( &(p->rect), &(p_cur[-1].rect) );
11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->p = stub;
11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( is_last_iter )
11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cmp_node.data = p_cur;
11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_WRITE_SEQ_ELEM( cmp_node, writer );
11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( layer == 0 )
11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur = _CV_NEXT_BASE_C1(p_cur,1);
11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur->c = 0;
11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur++;
11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* clear c's */
11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( layer > 0 )
11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_cur->c = 0;
11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_cur++;
11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !(i & 1) )
11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next1 -= size.width >> 1;
11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next3 -= size.width >> 1;
11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next1++;
11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next3++;
12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;
12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus icvUpdatePyrLinks_8u_C3
12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    (int layer, void *layer_data, CvSize size, void *parent_layer,
12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn     void *_writer, float threshold, int is_last_iter, void *_stub, CvWriteNodeFunction /*func*/)
12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j;
12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvListNode cmp_node;
12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidC3 *stub = (_CvPyramidC3 *) _stub;
12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidC3 *p_cur = (_CvPyramidC3 *) layer_data;
12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidC3 *p_next1 = (_CvPyramidC3 *) parent_layer;
12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidC3 *p_next3 = p_next1 + (size.width >> 1) + 1;
12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqWriter & writer = *(CvSeqWriter *) _writer;
12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < size.height; i++ )
12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < size.width; j += 2 )
12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float c1, c2, c3, c4;
12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvPyramidC3 *p;
12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* find pointer for the first pixel */
12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c1 = _CV_RGB_DIST( p_cur->c, p_next1[0].c );
12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c2 = _CV_RGB_DIST( p_cur->c, p_next1[1].c );
12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c3 = _CV_RGB_DIST( p_cur->c, p_next3[0].c );
12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c4 = _CV_RGB_DIST( p_cur->c, p_next3[1].c );
12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p = p_next1;
12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c2 )
12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next1 + 1;
12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c2;
12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c3 )
12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next3;
12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c3;
12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c4 )
12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next3 + 1;
12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c4;
12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 < threshold )
12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->p = p;
12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( layer == 0 )
12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p->a++;
12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur = _CV_NEXT_BASE_C3(p_cur,1);
12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( is_last_iter )
12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvMaxRoi1( &(p->rect), j, i );
12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int a = p_cur->a;
12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p->a += a;
12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur->c.blue = p_cur->c.green = p_cur->c.red = 0;
12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur++;
12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( is_last_iter && a != 0 )
12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvMaxRoi( &(p->rect), &(p_cur[-1].rect) );
12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->p = stub;
12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( is_last_iter /* && ( == 0 || p_cur->a != 0) */  )
12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cmp_node.data = p_cur;
12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_WRITE_SEQ_ELEM( cmp_node, writer );
12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( layer == 0 )
12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
12856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur = _CV_NEXT_BASE_C3(p_cur,1);
12866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
12876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
12886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
12896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur->c.blue = p_cur->c.green = p_cur->c.red = 0;
12906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur++;
12916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
12926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
12936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* find pointer for the second pixel */
12956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c1 = _CV_RGB_DIST( p_cur->c, p_next1[0].c );
12966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c2 = _CV_RGB_DIST( p_cur->c, p_next1[1].c );
12976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c3 = _CV_RGB_DIST( p_cur->c, p_next3[0].c );
12986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c4 = _CV_RGB_DIST( p_cur->c, p_next3[1].c );
12996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p = p_next1;
13016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next1++;
13026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c2 )
13046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next1;
13066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c2;
13076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c3 )
13096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next3;
13116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c3;
13126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next3++;
13156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 > c4 )
13166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p = p_next3;
13186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = c4;
13196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 < threshold )
13226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->p = p;
13246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( layer == 0 )
13266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
13276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p->a++;
13286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur = _CV_NEXT_BASE_C3(p_cur,1);
13296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( is_last_iter )
13306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvMaxRoi1( &(p->rect), j + 1, i );
13316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
13326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
13336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
13346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int a = p_cur->a;
13356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p->a += a;
13376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur->c.blue = p_cur->c.green = p_cur->c.red = 0;
13386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur++;
13396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( is_last_iter && a != 0 )
13406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvMaxRoi( &(p->rect), &(p_cur[-1].rect) );
13416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
13426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
13446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p_cur->p = stub;
13466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( is_last_iter /* && ( == 0 || p_cur->a != 0) */  )
13476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
13486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cmp_node.data = p_cur;
13496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_WRITE_SEQ_ELEM( cmp_node, writer );
13506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
13516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( layer == 0 )
13526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
13536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur = _CV_NEXT_BASE_C3(p_cur,1);
13546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
13556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
13566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
13576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur->c.blue = p_cur->c.green = p_cur->c.red = 0;
13586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p_cur++;
13596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
13606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
13626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* clear c's */
13646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( layer > 0 )
13656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
13666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_cur->c.blue = p_cur->c.green = p_cur->c.red = 0;
13676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_cur++;
13686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
13696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !(i & 1) )
13716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
13726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next1 -= size.width >> 1;
13736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next3 -= size.width >> 1;
13746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
13756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
13766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
13776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next1++;
13786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p_next3++;
13796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
13806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
13816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;
13836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
13886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    clusterization segmented components
13906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
13926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
13936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvExpandBaseLevelC1( _CvPyramid * base_p, _CvPyramid * p, _CvPyramidBase * start, int width )
13946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
13956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x = (int)((_CvPyramidBase *) base_p - start);
13966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int y = x / width;
13976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    x -= y * width;
13996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->a = 1;
14006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->rect.x1 = (ushort) x;
14016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->rect.y1 = (ushort) y;
14026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->rect.x2 = (ushort) (x + 1);
14036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->rect.y2 = (ushort) (y + 1);
14046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->c = base_p->c;
14056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus
14086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvSegmentClusterC1( CvSeq * cmp_seq, CvSeq * res_seq,
14096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     double threshold, _CvPyramid * first_level_end, CvSize first_level_size )
14106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
14116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const double eps = 1.;
14126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqWriter writer;
14136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqReader reader;
14146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramid temp_cmp;
14156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidBase *first_level_start = (_CvPyramidBase *) first_level_end -
14166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        first_level_size.width * first_level_size.height;
14176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int c, i, count = cmp_seq->total;
14186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartReadSeq( cmp_seq, &reader, 0 );
14206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartAppendToSeq( res_seq, &writer );
14216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( threshold < eps )
14236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
14246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* if threshold is too small then simply copy all
14256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           the components to the output sequence */
14266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < count; i++ )
14276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
14286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvConnectedComp comp;
14296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvPyramid *cmp = (_CvPyramid *) (((_CvListNode *) reader.ptr)->data);
14306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            Cv32suf _c;
14316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( cmp < first_level_end )
14336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvExpandBaseLevelC1( cmp, &temp_cmp, first_level_start,
14356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      first_level_size.width );
14366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cmp = &temp_cmp;
14376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _c.i = cvRound( cmp->c );
14406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cmp->c = _c.f;
14416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.value = cvRealScalar(_c.i);
14426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.area = cmp->a;
14436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.x = cmp->rect.x1;
14446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.y = cmp->rect.y1;
14456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.width = cmp->rect.x2 - cmp->rect.x1;
14466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.height = cmp->rect.y2 - cmp->rect.y1;
14476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.contour = 0;
14486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_WRITE_SEQ_ELEM( comp, writer );
14506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
14516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
14526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
14536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
14546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
14556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        _CvListNode stub_node;
14566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        _CvListNode *prev = &stub_node;
14576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        stub_node.next = 0;
14596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < count; i++ )
14616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
14626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvListNode *node = (_CvListNode *) reader.ptr;
14636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev->next = node;
14656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev = node;
14666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
14676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
14686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prev->next = 0;
14696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prev = stub_node.next;
14706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        while( prev )
14726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
14736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvListNode *node = prev->next;
14746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvListNode *acc = prev;
14756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvPyramid *cmp = (_CvPyramid *) (acc->data);
14766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvConnectedComp comp;
14776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float c0 = cmp->c;
14786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( cmp < first_level_end )
14806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvExpandBaseLevelC1( cmp, &temp_cmp, first_level_start,
14826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      first_level_size.width );
14836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
14856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                temp_cmp = *cmp;
14876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                temp_cmp.c *= temp_cmp.a;
14886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            acc->next = 0;
14916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            stub_node.next = 0;
14926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev = &stub_node;
14936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( node )
14956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cmp = (_CvPyramid *) (node->data);
14976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( fabs( c0 - cmp->c ) < threshold )
14986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
14996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    _CvPyramid temp;
15006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* exclude from global list and add to list of joint component */
15026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prev->next = node->next;
15036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    node->next = acc;
15046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    acc = node;
15056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( cmp < first_level_end )
15076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
15086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvExpandBaseLevelC1( cmp, &temp, first_level_start,
15096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              first_level_size.width );
15106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cmp = &temp;
15116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
15126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    temp_cmp.a += cmp->a;
15146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    temp_cmp.c += cmp->c * cmp->a;
15156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvMaxRoi( &(temp_cmp.rect), &(cmp->rect) );
15166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
15176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
15186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
15196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( prev == &stub_node )
15206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
15216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        stub_node.next = node;
15226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
15236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prev = node;
15246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
15256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                node = prev->next;
15266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
15276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( temp_cmp.a != 0 )
15296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
15306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c = cvRound( temp_cmp.c / temp_cmp.a );
15316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
15326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
15336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
15346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c = cvRound( c0 );
15356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
15366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            node = acc;
15376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( node )
15396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
15406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                Cv32suf _c;
15416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cmp = (_CvPyramid *) (node->data);
15426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _c.i = c; cmp->c = _c.f;
15436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                node = node->next;
15446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
15456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.value = cvRealScalar(c);
15476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.area = temp_cmp.a;
15486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.x = temp_cmp.rect.x1;
15496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.y = temp_cmp.rect.y1;
15506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.width = temp_cmp.rect.x2 - temp_cmp.rect.x1;
15516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.height = temp_cmp.rect.y2 - temp_cmp.rect.y1;
15526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.contour = 0;
15536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_WRITE_SEQ_ELEM( comp, writer );
15556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev = stub_node.next;
15566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
15576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
15586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvEndWriteSeq( &writer );
15606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;
15616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
15626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
15646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    clusterization segmented components
15666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
15686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
15696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvExpandBaseLevelC3( _CvPyramidC3 * base_p, _CvPyramidC3 * p,
15706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      _CvPyramidBaseC3 * start, int width )
15716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
15726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x = (int)((_CvPyramidBaseC3 *) base_p - start);
15736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int y = x / width;
15746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    x -= y * width;
15766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->a = 1;
15776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->rect.x1 = (ushort) x;
15786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->rect.y1 = (ushort) y;
15796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->rect.x2 = (ushort) (x + 1);
15806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->rect.y2 = (ushort) (y + 1);
15816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p->c = base_p->c;
15826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
15836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus
15856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvSegmentClusterC3( CvSeq * cmp_seq, CvSeq * res_seq,
15866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     double threshold,
15876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     _CvPyramidC3 * first_level_end, CvSize first_level_size )
15886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
15896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const double eps = 1.;
15906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqWriter writer;
15916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqReader reader;
15926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidC3 temp_cmp;
15936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _CvPyramidBaseC3 *first_level_start = (_CvPyramidBaseC3 *) first_level_end -
15946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        first_level_size.width * first_level_size.height;
15956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, count = cmp_seq->total;
15966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int c_blue, c_green, c_red;
15976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartReadSeq( cmp_seq, &reader, 0 );
15996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartAppendToSeq( res_seq, &writer );
16006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( threshold < eps )
16026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* if threshold is too small then simply copy all
16046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           the components to the output sequence */
16056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < count; i++ )
16066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvConnectedComp comp;
16086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvPyramidC3 *cmp = (_CvPyramidC3 *) (((_CvListNode *) reader.ptr)->data);
16096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            Cv32suf _c;
16106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( cmp < first_level_end )
16126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
16136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvExpandBaseLevelC3( cmp, &temp_cmp, first_level_start,
16146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      first_level_size.width );
16156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cmp = &temp_cmp;
16166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
16176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c_blue = cvRound( cmp->c.blue );
16196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c_green = cvRound( cmp->c.green );
16206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c_red = cvRound( cmp->c.red );
16216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _c.i = c_blue; cmp->c.blue = _c.f;
16226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _c.i = c_green; cmp->c.green = _c.f;
16236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _c.i = c_red; cmp->c.red = _c.f;
16246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.value = cvScalar( c_blue, c_green, c_red );
16256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.area = cmp->a;
16266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.x = cmp->rect.x1;
16276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.y = cmp->rect.y1;
16286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.width = cmp->rect.x2 - cmp->rect.x1;
16296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.height = cmp->rect.y2 - cmp->rect.y1;
16306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.contour = 0;
16316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_WRITE_SEQ_ELEM( comp, writer );
16336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
16346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
16376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        _CvListNode stub_node;
16396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        _CvListNode *prev = &stub_node;
16406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        stub_node.next = 0;
16426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < count; i++ )
16446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvListNode *node = (_CvListNode *) reader.ptr;
16466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev->next = node;
16486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev = node;
16496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_NEXT_SEQ_ELEM( sizeof( _CvListNode ), reader );
16506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prev->next = 0;
16526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prev = stub_node.next;
16536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        while( prev )
16556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvListNode *node = prev->next;
16576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvListNode *acc = prev;
16586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvPyramidC3 *cmp = (_CvPyramidC3 *) (acc->data);
16596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvConnectedComp comp;
16606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _CvRGBf c0 = cmp->c;
16616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( cmp < first_level_end )
16636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
16646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvExpandBaseLevelC3( cmp, &temp_cmp, first_level_start,
16656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      first_level_size.width );
16666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
16676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
16686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
16696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                temp_cmp = *cmp;
16706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                temp_cmp.c.blue *= temp_cmp.a;
16716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                temp_cmp.c.green *= temp_cmp.a;
16726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                temp_cmp.c.red *= temp_cmp.a;
16736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
16746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            acc->next = 0;
16766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            stub_node.next = 0;
16776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev = &stub_node;
16786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( node )
16806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
16816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cmp = (_CvPyramidC3 *) (node->data);
16826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( _CV_RGB_DIST( c0, cmp->c ) < threshold )
16836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
16846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    _CvPyramidC3 temp;
16856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* exclude from global list and add to list of joint component */
16876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prev->next = node->next;
16886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    node->next = acc;
16896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    acc = node;
16906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( cmp < first_level_end )
16926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
16936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvExpandBaseLevelC3( cmp, &temp, first_level_start,
16946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              first_level_size.width );
16956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cmp = &temp;
16966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
16976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    temp_cmp.a += cmp->a;
16996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    temp_cmp.c.blue += cmp->c.blue * cmp->a;
17006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    temp_cmp.c.green += cmp->c.green * cmp->a;
17016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    temp_cmp.c.red += cmp->c.red * cmp->a;
17026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvMaxRoi( &(temp_cmp.rect), &(cmp->rect) );
17036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
17046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
17056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
17066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( prev == &stub_node )
17076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
17086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        stub_node.next = node;
17096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
17106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prev = node;
17116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
17126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                node = prev->next;
17136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
17146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( temp_cmp.a != 0 )
17166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
17176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c_blue = cvRound( temp_cmp.c.blue / temp_cmp.a );
17186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c_green = cvRound( temp_cmp.c.green / temp_cmp.a );
17196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c_red = cvRound( temp_cmp.c.red / temp_cmp.a );
17206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
17216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
17226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
17236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c_blue = cvRound( c0.blue );
17246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c_green = cvRound( c0.green );
17256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c_red = cvRound( c0.red );
17266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
17276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            node = acc;
17286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( node )
17306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
17316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                Cv32suf _c;
17326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cmp = (_CvPyramidC3 *) (node->data);
17336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _c.i = c_blue; cmp->c.blue = _c.f;
17346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _c.i = c_green; cmp->c.green = _c.f;
17356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _c.i = c_red; cmp->c.red = _c.f;
17366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                node = node->next;
17376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
17386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.value = cvScalar( c_blue, c_green, c_red );
17406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.area = temp_cmp.a;
17416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.x = temp_cmp.rect.x1;
17426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.y = temp_cmp.rect.y1;
17436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.width = temp_cmp.rect.x2 - temp_cmp.rect.x1;
17446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.rect.height = temp_cmp.rect.y2 - temp_cmp.rect.y1;
17456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            comp.contour = 0;
17466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_WRITE_SEQ_ELEM( comp, writer );
17486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev = stub_node.next;
17496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
17506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvEndWriteSeq( &writer );
17536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;
17546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
17556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
17576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                 definition of the maximum roi size
17596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
17616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid
17626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvMaxRoi( _CvRect16u * max_rect, _CvRect16u * cur_rect )
17636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
17646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( max_rect->x2 == 0 )
17656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *max_rect = *cur_rect;
17666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
17676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( max_rect->x1 > cur_rect->x1 )
17696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            max_rect->x1 = cur_rect->x1;
17706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( max_rect->y1 > cur_rect->y1 )
17716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            max_rect->y1 = cur_rect->y1;
17726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( max_rect->x2 < cur_rect->x2 )
17746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            max_rect->x2 = cur_rect->x2;
17756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( max_rect->y2 < cur_rect->y2 )
17766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            max_rect->y2 = cur_rect->y2;
17776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
17796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid
17816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvMaxRoi1( _CvRect16u * max_rect, int x, int y )
17826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
17836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( max_rect->x2 == 0 )
17846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        max_rect->x1 = (ushort) x;
17866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        max_rect->y1 = (ushort) y;
17876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ++x;
17896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ++y;
17906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        max_rect->x2 = (ushort) x;
17926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        max_rect->y2 = (ushort) y;
17936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
17956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( max_rect->x1 > x )
17976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            max_rect->x1 = (ushort) x;
17986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( max_rect->y1 > y )
17996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            max_rect->y1 = (ushort) y;
18006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ++x;
18026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ++y;
18036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( max_rect->x2 < x )
18056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            max_rect->x2 = (ushort) x;
18066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( max_rect->y2 < y )
18076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            max_rect->y2 = (ushort) y;
18086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
18106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
18136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name:    cvPyrSegmentation
18146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose:
18156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      segments an image using pyramid-linking technique
18166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
18176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:
18186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      src - source image
18196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      dst - destination image
18206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      comp - pointer to returned connected component sequence
18216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      storage - where the sequence is stored
18226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      level - maximal pyramid level
18236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      threshold1 - first threshold, affecting on detalization level when pyramid
18246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                   is built.
18256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      threshold2 - second threshold - affects on final components merging.
18266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns:
18276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
18286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      Source and destination image must be equal types and channels
18296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
18306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
18316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPyrSegmentation( IplImage * src,
18326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   IplImage * dst,
18336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   CvMemStorage * storage,
18346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   CvSeq ** comp, int level, double threshold1, double threshold2 )
18356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
18366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize src_size, dst_size;
18376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar *src_data = 0;
18386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar *dst_data = 0;
18396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int src_step = 0, dst_step = 0;
18406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int thresh1 = cvRound( threshold1 );
18416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int thresh2 = cvRound( threshold2 );
18426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvPyrSegmentation" );
18446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
18466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src->depth != IPL_DEPTH_8U )
18486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
18496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src->depth != dst->depth || src->nChannels != dst->nChannels )
18516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "src and dst have different formats" );
18526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetRawData( src, &src_data, &src_step, &src_size );
18546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetRawData( dst, &dst_data, &dst_step, &dst_size );
18556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src_size.width != dst_size.width ||
18576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src_size.height != dst_size.height )
18586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "src and dst have different ROIs" );
18596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch (src->nChannels)
18616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case 1:
18636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IPPI_CALL( icvPyrSegmentation8uC1R( src_data, src_step,
18646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            dst_data, dst_step,
18656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            src_size,
18666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            CV_GAUSSIAN_5x5,
18676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            comp, storage, level, thresh1, thresh2 ));
18686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
18696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case 3:
18706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IPPI_CALL( icvPyrSegmentation8uC3R( src_data, src_step,
18716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            dst_data, dst_step,
18726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            src_size,
18736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            CV_GAUSSIAN_5x5,
18746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            comp, storage, level, thresh1, thresh2 ));
18756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
18766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default:
18776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
18786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
18806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
18816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
1884