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
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cvaux.h"
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 0
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//#include "windows.h"
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//#define ALPHA_EXPANSION
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifndef ALPHA_EXPANSION
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #define ALPHA_BETA_EXCHANGE
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define MAX_LABEL 20
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_MODULE(xxx) \
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( (xxx) < 0 ? -(xxx) : (xxx) )
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_MAX3(xxx1,xxx2,xxx3) \
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( (xxx1) > (xxx2) && (xxx1) > (xxx3) ? (xxx1) : \
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (xxx2) > (xxx3) ? (xxx2) : (xxx3) )
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_MIN2(xxx1,xxx2) \
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( (xxx1) < (xxx2) ? (xxx1) : (xxx2) )
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define getSizeForGraph(xxxType) \
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( sizeof(xxxType) < 8 ? 8 : sizeof(xxxType) + 4 - sizeof(xxxType) % 4 )
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define INT_INFINITY 1000000000
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define MAX_DIFFERENCE 10
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// struct Vertex is used for storing vertices of graph
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      coord       - coordinate corresponding pixel on the real image line
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstruct Vertex
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvGraphVtx vtx;
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coord;
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// struct Edge is used for storing edges of graph
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      weight      - weight of the edge ( maximum flow via the edge )
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      flow        - current flow via the edge
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      srcVtx      - coordinate of source vertex on the real image line
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      destVtx     - coordinate of destination vertex on the real image line
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstruct Edge
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_GRAPH_EDGE_FIELDS()
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int weight;
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int flow;
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int srcVtx;
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int destVtx;
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// function vFunc is energy function which determines the difference
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   between two labels ( alpha and beta )
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      alpha       - label number one
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      beta        - label number two
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline int vFunc( int alpha, int beta )
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( alpha == beta )
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return 0;
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return /*1*//*5*/10;
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// function dFunc is energy function which determines energy of interaction
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   between pixel ( having coordinate xCoord ) and label
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//          leftLine        - line of left image
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//          rightLine       - line of right image
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//          xCoord          - coordinate of pixel on the left image
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//          label           - label corresponding to the pixel
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//          width           - width of the image line in pixels
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline int dFunc( unsigned char* leftLine,
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  unsigned char* rightLine,
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  int xCoord,
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  int label,
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  int width)
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( xCoord >= 0 && xCoord < width );
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int r, g, b;
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int yCoord = xCoord + label;
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( yCoord >= width )
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        yCoord = width;
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( yCoord < 0 )
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        yCoord = 0;
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    r = leftLine[ 3 * xCoord     ] - rightLine[ 3 * yCoord     ];
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    g = leftLine[ 3 * xCoord + 1 ] - rightLine[ 3 * yCoord + 1 ];
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    b = leftLine[ 3 * xCoord + 2 ] - rightLine[ 3 * yCoord + 2 ];
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    r = CV_MODULE( r );
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    g = CV_MODULE( g );
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    b = CV_MODULE( b );
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_MAX3( r, g, b );
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// function allocTempMem allocates all temporary memory needed for work
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   of some function
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      memPtr          - pointer to pointer to the large block of memory
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      verticesPtr     - pointer to pointer to block of memory for
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        temporary storing vertices
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      width           - width of line in pixels
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid allocTempMem( int** memPtr,
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int** verticesPtr,
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int width )
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* tempPtr = ( int* ) malloc( ( width + 2 ) * 7 * sizeof( int ) );
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *verticesPtr = tempPtr;
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *memPtr = *verticesPtr + width + 2;
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// function freeTempMem frees all allocated by allocTempMem function memory
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      memPtr          - pointer to pointer to the large block of memory
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      verticesPtr     - pointer to pointer to block of memory for
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        temporary storing vertices
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid freeTempMem( int** memPtr,
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  int** verticesPtr )
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    free( ( void* )( *verticesPtr ) );
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *verticesPtr = NULL;
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *memPtr = NULL;
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// function makeGraph creates initial graph to find maximum flow in it
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      graphPtr        - pointer to pointer to CvGraph structure to be filled
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      leftLine        - pointer to the left image line
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      rightLine       - pointer to the right image line
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      alpha           - label number one for doing exchange
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      beta            - label number two for doing exchange
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      corr            - pointer to array of correspondences ( each element
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        of array includes disparity of pixel on right image
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        for pixel each on left image ). This pointer direct
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        to correspondence ofr one line only
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      width           - width of image lines in pixels
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      storage         - pointer to CvMemStorage structure which contains
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        memory storage
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid makeGraph( CvGraph** graphPtr,
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                unsigned char* leftLine,
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                unsigned char* rightLine,
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int alpha,
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int beta,
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int* corr,
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int width,
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvMemStorage* storage )
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( *graphPtr )  {
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvClearGraph( *graphPtr );
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*else {*/
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *graphPtr = cvCreateGraph( CV_SEQ_KIND_GRAPH | CV_GRAPH_FLAG_ORIENTED,
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   sizeof( CvGraph ),
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   getSizeForGraph( Vertex ),
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   getSizeForGraph( Edge ),
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   storage );
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*}*/
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvGraph* graph = *graphPtr;
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #ifdef ALPHA_BETA_EXCHANGE
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvGraphVtx* newVtxPtr;
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < width; i ++ )
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( corr[i] == alpha || corr[i] == beta ) {
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvGraphAddVtx( graph, NULL, &newVtxPtr );
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Vertex* )newVtxPtr ) -> coord = i;
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* for( i = 0; i < width; i ++ ) */
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGraphAddVtx( graph, NULL, &newVtxPtr );
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( newVtxPtr )
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ( ( Vertex* )newVtxPtr ) -> coord = -2; /* adding alpha vertex */
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGraphAddVtx( graph, NULL, &newVtxPtr );
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( newVtxPtr )
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ( ( Vertex* )newVtxPtr ) -> coord = -1; /* adding beta vertex */
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int alphaVtx = graph -> total - 2;
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int betaVtx = graph -> total - 1;
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvGraphEdge* newEdgePtr;
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvGraphVtx* vtxPtr;
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( graph -> total > 2 )
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < alphaVtx; i ++ )
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            vtxPtr = cvGetGraphVtx( graph, i );
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* adding edge oriented from alpha vertex to current vertex */
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvGraphAddEdge( graph, alphaVtx, i, NULL, &newEdgePtr );
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Edge* )newEdgePtr ) -> weight = dFunc( leftLine,
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rightLine,
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ( ( Vertex* )vtxPtr ) -> coord,
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                alpha,
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                width );
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Edge* )newEdgePtr ) -> flow = 0;
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i != 0 ) {
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvGraphVtx* tempVtxPtr = cvGetGraphVtx( graph, i - 1 );
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* if vertices are neighbours */
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( ( ( Vertex* )tempVtxPtr ) -> coord + 1 ==
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Vertex* )vtxPtr ) -> coord )
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )newEdgePtr ) -> weight +=
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        vFunc( corr[ ( ( Vertex* )tempVtxPtr ) -> coord ],
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               alpha );
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* adding neighbour edge oriented from current vertex
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       to the previous one */
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvGraphEdge* tempEdgePtr;
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cvGraphAddEdge( graph, i, i - 1, NULL, &tempEdgePtr );
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )tempEdgePtr ) -> weight = vFunc( alpha, beta );
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )tempEdgePtr ) -> flow = 0;
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )tempEdgePtr ) -> srcVtx =
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ( ( Vertex* )vtxPtr ) -> coord;
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )tempEdgePtr ) -> destVtx =
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ( ( Vertex* )tempVtxPtr ) -> coord;
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } /* if( i != 0 ) */
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i != alphaVtx - 1 ) {
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvGraphVtx* tempVtxPtr = cvGetGraphVtx( graph, i + 1 );
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* if vertices are neighbours */
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( ( ( Vertex* )tempVtxPtr ) -> coord - 1 ==
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Vertex* )vtxPtr ) -> coord )
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )newEdgePtr ) -> weight +=
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        vFunc( corr[ ( ( Vertex* )tempVtxPtr ) -> coord ],
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               alpha );
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* adding neighbour edge oriented from current vertex
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       to the next one */
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvGraphEdge* tempEdgePtr;
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cvGraphAddEdge( graph, i, i + 1, NULL, &tempEdgePtr );
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )tempEdgePtr ) -> weight = vFunc( alpha, beta );
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )tempEdgePtr ) -> flow = 0;
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )tempEdgePtr ) -> srcVtx =
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ( ( Vertex* )vtxPtr ) -> coord;
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )tempEdgePtr ) -> destVtx =
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ( ( Vertex* )tempVtxPtr ) -> coord;
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } /* if( i != alphaVtx - 1 ) */
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Edge* )newEdgePtr ) -> flow = 0;
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Edge* )newEdgePtr ) -> srcVtx = -1; /* source vertex is alpha
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                       vertex */
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Edge* )newEdgePtr ) -> destVtx = ( ( Vertex* )vtxPtr ) -> coord;
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* adding edge oriented from current vertex to beta vertex */
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvGraphAddEdge( graph, i, betaVtx, NULL, &newEdgePtr );
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Edge* )newEdgePtr ) -> weight = dFunc( leftLine,
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rightLine,
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ( ( Vertex* )vtxPtr ) -> coord,
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                beta,
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                width );
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Edge* )newEdgePtr ) -> flow = 0;
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i != 0 ) {
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvGraphVtx* tempVtxPtr = cvGetGraphVtx( graph, i - 1 );
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* if vertices are neighbours */
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( ( ( Vertex* )tempVtxPtr ) -> coord + 1 ==
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Vertex* )vtxPtr ) -> coord )
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )newEdgePtr ) -> weight +=
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        vFunc( corr[ ( ( Vertex* )tempVtxPtr ) -> coord ],
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               beta );
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } /* if( i != 0 ) */
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i != alphaVtx - 1 ) {
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvGraphVtx* tempVtxPtr = cvGetGraphVtx( graph, i + 1 );
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* if vertices are neighbours */
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( ( ( Vertex* )tempVtxPtr ) -> coord - 1 ==
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Vertex* )vtxPtr ) -> coord )
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( ( Edge* )newEdgePtr ) -> weight +=
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        vFunc( corr[ ( ( Vertex* )tempVtxPtr ) -> coord ],
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               beta );
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } /* if( i != alphaVtx - 1 ) */
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Edge* )newEdgePtr ) -> flow = 0;
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Edge* )newEdgePtr ) -> srcVtx =
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ( ( Vertex* )vtxPtr ) -> coord;
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Edge* )newEdgePtr ) -> destVtx = -2; /* destination vertex is
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                        beta vertex */
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* for( i = 0; i < graph -> total - 2; i ++ ) */
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* if( graph -> total > 2 ) */
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #endif /* #ifdef ALPHA_BETA_EXCHANGE */
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #ifdef ALPHA_EXPANSION
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #endif /* #ifdef ALPHA_EXPANSION */
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} /* makeGraph */
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// function makeHelpGraph creates help graph using initial graph
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      graph           - pointer to initial graph ( represented by CvGraph
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        structure )
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      hlpGraphPtr     - pointer to pointer to new help graph
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      storage         - pointer to CvStorage structure
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      mem             - pointer to memory allocated by allocTempMem function
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      vertices        - pointer to memory allocated by allocTempMem function
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      verticesCountPtr- pointer to value containing number of vertices
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        in vertices array
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      width           - width of image line in pixels
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennint makeHelpGraph( CvGraph* graph,
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   CvGraph** hlpGraphPtr,
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   CvMemStorage* storage,
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int* mem,
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int* vertices,
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int* verticesCountPtr,
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int width )
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int u, v;
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* order = mem;
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* lengthArr = order + width + 2;
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int s = graph -> total - 2; /* source vertex */
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int t = graph -> total - 1; /* terminate vertex */
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int orderFirst;
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int orderCount;
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int &verticesCount = *verticesCountPtr;
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvGraph* hlpGraph;
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( *hlpGraphPtr )  {
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvClearGraph( *hlpGraphPtr );
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else {
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *hlpGraphPtr = cvCreateGraph( CV_SEQ_KIND_GRAPH |
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                          CV_GRAPH_FLAG_ORIENTED,
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      sizeof( CvGraph ),
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      getSizeForGraph( Vertex ),
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      getSizeForGraph( Edge ),
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      storage );
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hlpGraph = *hlpGraphPtr;
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* initialization */
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( u = 0; u < graph -> total; u ++ )
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lengthArr[ u ] = INT_INFINITY;
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvGraphAddVtx( hlpGraph, NULL, NULL );
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* for( u = 0; u < graph -> total - 1; u ++ ) */
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    orderFirst = 0;
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    orderCount = 0;
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    verticesCount = 0;
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    lengthArr[ s ] = 0;
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* add vertex s to order */
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    order[ orderCount ] = s;
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    orderCount ++;
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( orderCount != orderFirst )
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* getting u from order */
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        u = order[ orderFirst ];
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        orderFirst ++;
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* adding u to vertex array */
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        vertices[ verticesCount ] = u;
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        verticesCount ++;
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int ofs;
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvGraphVtx* graphVtx = cvGetGraphVtx( graph, u );
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* processing all vertices outgoing from vertex u */
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvGraphEdge* graphEdge = graphVtx -> first;
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        while( graphEdge )
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int tempVtxIdx = cvGraphVtxIdx( graph, graphEdge -> vtx[1] );
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ofs = tempVtxIdx == u;
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !ofs )
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v = tempVtxIdx;
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvGraphEdge* tempGraphEdge = cvFindGraphEdge( graph, u, v );
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( ( lengthArr[ u ] < lengthArr[ v ] )
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    && ( lengthArr[ v ] <= lengthArr[ t ] )
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    && ( ( ( Edge* )tempGraphEdge ) -> flow <
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ( ( Edge* )tempGraphEdge ) -> weight ) )
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( lengthArr[ v ] == INT_INFINITY )
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        /* adding vertex v to order */
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        order[ orderCount ] = v;
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        orderCount ++;
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        lengthArr[ v ] = lengthArr[ u ] + 1;
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CvGraphEdge* tempGraphEdge2;
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cvGraphAddEdge( hlpGraph, u, v, NULL, &tempGraphEdge2 );
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ( ( Edge* )tempGraphEdge2 ) -> flow = 0;
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ( ( Edge* )tempGraphEdge2 ) -> weight =
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            ( ( Edge* )tempGraphEdge ) -> weight -
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            ( ( Edge* )tempGraphEdge ) -> flow;
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    } /* if( length[ v ] == INT_INFINITY ) */
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } /* if( ( lengthArr[ u ] < lengthArr[ v ] ) ... */
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } /* if( !ofs ) */
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            graphEdge = graphEdge -> next[ ofs ];
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* while( graphEdge ) */
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* processing all vertices incoming to vertex u */
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        graphEdge = graphVtx -> first;
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        while( graphEdge )
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int tempVtxIdx = cvGraphVtxIdx( graph, graphEdge -> vtx[1] );
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ofs = tempVtxIdx == u;
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( ofs )
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tempVtxIdx = cvGraphVtxIdx( graph, graphEdge -> vtx[0] );
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v = tempVtxIdx;
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvGraphEdge* tempGraphEdge = cvFindGraphEdge( graph, v, u );
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( ( lengthArr[ u ] < lengthArr[ v ] )
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    && ( lengthArr[ v ] <= lengthArr[ t ] )
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    && ( ( ( Edge* )tempGraphEdge ) -> flow > 0 ) )
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( lengthArr[ v ] == INT_INFINITY )
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        /* adding vertex v to order */
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        order[ orderCount ] = v;
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        orderCount ++;
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        lengthArr[ v ] = lengthArr[ u ] + 1;
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CvGraphEdge* tempGraphEdge3 = cvFindGraphEdge( hlpGraph, u, v );
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( tempGraphEdge3 == NULL ||
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            ( ( Edge* )tempGraphEdge3 ) -> weight == 0 )
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvGraphEdge* tempGraphEdge2;
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cvGraphAddEdge( hlpGraph, u, v, NULL,
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                &tempGraphEdge2 );
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            ( ( Edge* )tempGraphEdge2 ) -> flow = 0;
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            ( ( Edge* )tempGraphEdge2 ) -> weight = 0;
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        } /* if( tempGraphEdge3 == NULL || ... */
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ( ( Edge* )tempGraphEdge3 ) -> weight +=
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            ( ( Edge* )tempGraphEdge ) -> flow;
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    } /* if( length[ v ] == INT_INFINITY ) */
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } /* if( ( lengthArr[ u ] < lengthArr[ v ] ) ... */
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } /* if( ofs ) */
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            graphEdge = graphEdge -> next[ ofs ];
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* while( graphEdge ) */
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* while( orderCount != orderFirst ) */
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < hlpGraph -> total - 2; i ++ )
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvGraphVtx* hlpGraphVtxTemp = cvGetGraphVtx( hlpGraph, i );
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( hlpGraphVtxTemp ) {
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !hlpGraphVtxTemp -> first ) {
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvGraphRemoveVtxByPtr( hlpGraph, hlpGraphVtxTemp );
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* for( i = 0; i < hlpGraph -> total - 2; i ++ ) */
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return lengthArr[ t ];
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} /* makeHelpGraph */
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// function makePseudoMaxFlow increases flow in graph by using hlpGraph
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      graph           - pointer to initial graph
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      hlpGraph        - pointer to help graph
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      vertices        - pointer to vertices array
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      verticesCount   - number of vertices in vertices array
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      mem             - pointer to memory allocated by allocTempMem function
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      width           - width of image line in pixels
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid makePseudoMaxFlow( CvGraph* graph,
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CvGraph* hlpGraph,
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int* vertices,
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int verticesCount,
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int* mem,
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int width )
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int stekCount;
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int orderFirst;
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int orderCount;
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int v, u;
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* stek = mem;
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* order = stek + width + 2;
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* incomFlow = order + width + 2;
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* outgoFlow = incomFlow + width + 2;
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* flow = outgoFlow + width + 2;
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* cargo = flow+ width + 2;
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int s = graph -> total - 2; /* source vertex */
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int t = graph -> total - 1; /* terminate vertex */
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int realVerticesCount = verticesCount;
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    stekCount = 0;
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < verticesCount; i ++ )
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        v = vertices[ i ];
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        incomFlow[ v ] = outgoFlow[ v ] = 0;
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( v == s ) {
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            incomFlow[ v ] = INT_INFINITY;
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* if( v == s ) */
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else {
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvGraphVtx* hlpGraphVtx = cvGetGraphVtx( hlpGraph, v );
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvGraphEdge* hlpGraphEdge = hlpGraphVtx -> first;
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ofs;
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( hlpGraphEdge )
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int vtxIdx = cvGraphVtxIdx( hlpGraph,
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    hlpGraphEdge -> vtx[1] );
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ofs = vtxIdx == v;
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( ofs )
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    incomFlow[ v ] += ( ( Edge* )hlpGraphEdge ) -> weight;
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } /* if( ofs ) */
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                hlpGraphEdge = hlpGraphEdge -> next[ ofs ];
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } /* while( hlpGraphEdge ) */
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* if( v == s ) else */
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( v == t ) {
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            outgoFlow[ v ] = INT_INFINITY;
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* if( v == t ) */
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else {
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvGraphVtx* hlpGraphVtx = cvGetGraphVtx( hlpGraph, v );
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvGraphEdge* hlpGraphEdge = hlpGraphVtx -> first;
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ofs;
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( hlpGraphEdge )
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int vtxIdx = cvGraphVtxIdx( hlpGraph,
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    hlpGraphEdge -> vtx[1] );
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ofs = vtxIdx == v;
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !ofs )
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    outgoFlow[ v ] += ( ( Edge* )hlpGraphEdge ) -> weight;
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } /* if( ofs ) */
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                hlpGraphEdge = hlpGraphEdge -> next[ ofs ];
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } /* while( hlpGraphEdge ) */
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* if( v == t ) else */
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        flow[ v ] = CV_MIN2( incomFlow[ v ], outgoFlow[ v ] );
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !flow[ v ] ) {
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            stek[ stekCount ] = v;
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            stekCount ++;
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* if( !flow[ v ] ) */
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* for( i = 0; i < verticesCount; i ++ ) */
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < verticesCount; i ++ )
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        v = vertices[ i ];
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cargo[ v ] = 0;
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* for( i = 0; i < verticesCount; i ++ ) */
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( realVerticesCount > 2 )
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* deleting all vertices included in stek */
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        while( stekCount )
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            v = stek[ stekCount - 1 ];
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            stekCount --;
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* deleting edges incoming to v and outgoing from v */
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ofs;
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvGraphVtx* hlpGraphVtx = cvGetGraphVtx( hlpGraph, v );
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvGraphEdge* hlpGraphEdge;
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( hlpGraphVtx ) {
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                hlpGraphEdge = hlpGraphVtx -> first;
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else {
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                hlpGraphEdge = NULL;
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( hlpGraphEdge )
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvGraphVtx* hlpGraphVtx2 = hlpGraphEdge -> vtx[ 1 ];
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int hlpGraphVtxIdx2 = cvGraphVtxIdx( hlpGraph,
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    hlpGraphVtx2 );
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ofs = hlpGraphVtxIdx2 == v;
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( ofs )
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* hlpGraphEdge is incoming edge */
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvGraphVtx* hlpGraphVtx3 = hlpGraphEdge -> vtx[0];
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    u = cvGraphVtxIdx( hlpGraph,
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       hlpGraphVtx3 );
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    outgoFlow[ u ] -= ( ( Edge* )hlpGraphEdge ) -> weight
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        - ( ( Edge* )hlpGraphEdge ) -> flow;
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cvGraphRemoveEdgeByPtr( hlpGraph,
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            hlpGraphVtx3,
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            hlpGraphVtx2 );
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( flow[ u ] != 0 ) {
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        flow[ u ] = CV_MIN2( incomFlow[u], outgoFlow[u] );
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( flow[ u ] == 0 ) {
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            stek[ stekCount ] = u;
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            stekCount ++;
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } /* if( ofs ) */
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* hlpGraphEdge is outgoing edge */
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvGraphVtx* hlpGraphVtx3 = hlpGraphEdge -> vtx[1];
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int u = cvGraphVtxIdx( hlpGraph,
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              hlpGraphVtx3 );
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    incomFlow[ u ] -= ( ( Edge* )hlpGraphEdge ) -> weight
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        - ( ( Edge* )hlpGraphEdge ) -> flow;
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cvGraphRemoveEdgeByPtr( hlpGraph,
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            hlpGraphVtx2,
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            hlpGraphVtx3 );
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( flow[ u ] != 0 ) {
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        flow[ u ] = CV_MIN2( incomFlow[u], outgoFlow[u] );
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( flow[ u ] == 0 ) {
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            stek[ stekCount ] = u;
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            stekCount ++;
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } /* if( ofs ) else */
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                hlpGraphEdge = hlpGraphEdge -> next[ ofs ];
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } /* while( hlpGraphEdge ) */
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* deleting vertex v */
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvGraphRemoveVtx( hlpGraph, v );
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            realVerticesCount --;
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* while( stekCount ) */
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( realVerticesCount > 2 ) /* the flow is not max still */
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int p = INT_INFINITY;
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int r = -1;
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvGraphVtx* graphVtx;
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( realVerticesCount == 3 ) {
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r = r;
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < hlpGraph -> total - 2; i ++ )
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                graphVtx = cvGetGraphVtx( hlpGraph, i );
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( graphVtx ) {
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v = cvGraphVtxIdx( hlpGraph, graphVtx );
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( flow[ v ] < p ) {
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        r = v;
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        p = flow[ v ];
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } /* for( i = 0; i < hlpGraph -> total - 2; i ++ ) */
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* building of size p flow from r to t */
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            orderCount = orderFirst = 0;
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            order[ orderCount ] = r;
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            orderCount ++;
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            v = order[ orderFirst ];
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            orderFirst ++;
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cargo[ r ] = p;
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            do /* while( v != t ) */
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                incomFlow[ v ] -= cargo[ v ];
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                outgoFlow[ v ] -= cargo[ v ];
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                flow[ v ] -= cargo[ v ];
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( flow[ v ] == 0 ) {
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    stek[ stekCount ] = v;
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    stekCount ++;
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( v == t ) {
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cargo[ v ] = p;
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int ofs;
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvGraphVtx* hlpGraphVtx2;
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvGraphVtx* hlpGraphVtx = cvGetGraphVtx( hlpGraph, v );
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvGraphEdge* hlpGraphEdge = hlpGraphVtx -> first;
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvGraphEdge* hlpGraphEdge2 = NULL;
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    while( hlpGraphEdge && cargo[ v ] > 0 )
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        hlpGraphVtx2 = hlpGraphEdge -> vtx[ 1 ];
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        u = cvGraphVtxIdx( hlpGraph, hlpGraphVtx2 );
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ofs = u == v;
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( !ofs )
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            if( cargo[ u ] == 0 ) {
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                order[ orderCount ] = u;
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                orderCount ++;
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int delta = ( ( Edge* )hlpGraphEdge ) -> weight
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                - ( ( Edge* )hlpGraphEdge ) -> flow;
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            delta = CV_MIN2( cargo[ v ], delta );
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            ( ( Edge* )hlpGraphEdge ) -> flow += delta;
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cargo[ v ] -= delta;
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cargo[ u ] += delta;
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            if( ( ( Edge* )hlpGraphEdge ) -> weight ==
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                ( ( Edge* )hlpGraphEdge ) -> flow )
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                /* deleting hlpGraphEdge */
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                hlpGraphEdge2 = hlpGraphEdge -> next[ ofs ];
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                CvGraphEdge* graphEdge =
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    cvFindGraphEdge( graph, v, u );
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                ( ( Edge* )graphEdge ) -> flow +=
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    ( ( Edge* )hlpGraphEdge ) -> flow;
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                cvGraphRemoveEdgeByPtr( hlpGraph,
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    hlpGraphEdge -> vtx[0],
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    hlpGraphEdge -> vtx[1] );
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        } /* if( !ofs ) */
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( hlpGraphEdge2 ) {
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            hlpGraphEdge = hlpGraphEdge2;
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            hlpGraphEdge2 = NULL;
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        else {
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            hlpGraphEdge = hlpGraphEdge -> next[ ofs ];
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    } /* while( hlpGraphEdge && cargo[ v ] > 0 ) */
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } /* if( v == t ) else */
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v = order[ orderFirst ];
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                orderFirst ++;
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } while( v != t ); /* do */
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* building of size p flow from s to r */
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            orderCount = orderFirst = 0;
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            order[ orderCount ] = r;
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            orderCount ++;
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            v = order[ orderFirst ];
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            orderFirst ++;
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cargo[ r ] = p;
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            do /* while( v != s ) */
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( v != r )
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    incomFlow[ v ] -= cargo[ v ];
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    outgoFlow[ v ] -= cargo[ v ];
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    flow[ v ] -= cargo[ v ];
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( flow[ v ] == 0 ) {
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        stek[ stekCount ] = v;
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        stekCount ++;
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } /* if( v != r ) */
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( v == s ) {
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cargo[ v ] = 0;
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } /* if( v == s ) */
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int ofs;
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvGraphVtx* hlpGraphVtx = cvGetGraphVtx( hlpGraph, v );
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvGraphEdge* hlpGraphEdge = hlpGraphVtx -> first;
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvGraphEdge* hlpGraphEdge2 = NULL;
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    while( hlpGraphEdge && cargo[ v ] > 0 )
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        u = cvGraphVtxIdx( hlpGraph,
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                hlpGraphEdge -> vtx[ 1 ] );
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ofs = u == v;
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( ofs )
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            u = cvGraphVtxIdx( hlpGraph,
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    hlpGraphEdge -> vtx[ 0 ] );
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            if( cargo[ u ] == 0 ) {
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                order[ orderCount ] = u;
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                orderCount ++;
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int delta = ( ( Edge* )hlpGraphEdge ) -> weight
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                - ( ( Edge* )hlpGraphEdge ) -> flow;
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            delta = CV_MIN2( cargo[ v ], delta );
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            (( ( Edge* )hlpGraphEdge ) -> flow) += delta;
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cargo[ v ] -= delta;
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cargo[ u ] += delta;
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            if( ( ( Edge* )hlpGraphEdge ) -> weight ==
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                ( ( Edge* )hlpGraphEdge ) -> flow )
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                hlpGraphEdge2 = hlpGraphEdge -> next[ ofs ];
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                CvGraphEdge* graphEdge =
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    cvFindGraphEdge( graph, u, v );
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                ( ( Edge* )graphEdge ) -> flow +=
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    ( ( Edge* )hlpGraphEdge ) -> flow;
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                cvGraphRemoveEdgeByPtr( hlpGraph,
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    hlpGraphEdge -> vtx[0],
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    hlpGraphEdge -> vtx[1] );
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        } /* if( ofs ) */
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( hlpGraphEdge2 ) {
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            hlpGraphEdge = hlpGraphEdge2;
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            hlpGraphEdge2 = NULL;
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        else {
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            hlpGraphEdge = hlpGraphEdge -> next[ ofs ];
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    } /* while( hlpGraphEdge && cargo[ v ] > 0 ) */
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } /* if( v == s ) else */
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v = order[ orderFirst ]; //added
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                orderFirst ++; //added
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } while( v != s ); /* do */
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* if( hlpGraph -> total > 2 ) */
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* while( hlpGraph -> total > 2 ) */
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} /* makePseudoMaxFlow */
8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// function oneStep produces one alpha-beta exchange for one line of images
8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      leftLine        - pointer to the left image line
8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      rightLine       - pointer to the right image line
8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      alpha           - label number one
8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      beta            - label number two
8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      corr            - pointer to correspondence array for this line
8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      width           - width of image line in pixels
8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      mem             - pointer to memory allocated by allocTempMem function
8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      vertices        - pointer to vertices array allocated by allocTempMem
8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        function
8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      storage         - pointer to CvMemStorage structure
8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool oneStep( unsigned char* leftLine,
8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              unsigned char* rightLine,
8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              int alpha,
8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              int beta,
8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              int* corr,
8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              int width,
8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              int* mem,
9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              int* vertices,
9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              CvMemStorage* storage )
9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvGraph* graph = NULL;
9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvGraph* hlpGraph = NULL;
9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMemStoragePos storagePos;
9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool change = false;
9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvSaveMemStoragePos( storage, &storagePos );
9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int verticesCount;
9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    makeGraph( &graph, leftLine, rightLine, alpha, beta, corr, width, storage );
9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int s = graph -> total - 2; /* source vertex - alpha vertex */
9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //int t = graph -> total - 1; /* terminate vertex - beta vertex */
9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int length = makeHelpGraph( graph,
9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                &hlpGraph,
9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                storage,
9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                mem,
9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                vertices,
9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                &verticesCount,
9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                width );
9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( length != INT_INFINITY )
9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        change = true;
9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        makePseudoMaxFlow( graph,
9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           hlpGraph,
9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           vertices,
9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           verticesCount,
9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           mem,
9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           width );
9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvClearGraph( hlpGraph );
9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        length = makeHelpGraph( graph,
9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                &hlpGraph,
9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                storage,
9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                mem,
9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                vertices,
9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                &verticesCount,
9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                width );
9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* while( length != INT_INFINITY ) */
9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coord;
9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvGraphVtx* graphVtx;
9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < s; i ++ )
9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvGraphEdge* graphEdge = cvFindGraphEdge( graph, s, i );
9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ( ( Edge* )graphEdge ) -> weight ==
9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ( ( Edge* )graphEdge ) -> flow )
9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        { /* this vertex must have alpha label */
9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            graphVtx = cvGetGraphVtx( graph, i );
9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            coord = ( ( Vertex* )graphVtx )-> coord;
9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( corr[ coord ] != alpha ) {
9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                corr[ coord ] = alpha; //added
9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                change = true;
9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else {
9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                corr[ coord ] = alpha;
9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* if( ( ( Edge* )graphEdge ) -> weight == ... */
9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        { /* this vertex must have beta label */
9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            graphVtx = cvGetGraphVtx( graph, i );
9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            coord = ( ( Vertex* )graphVtx )-> coord;
9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( corr[ coord ] != beta ) {
9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                corr[ coord ] = beta; //added
9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                change = true;
9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else {
9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                corr[ coord ] = beta;
9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* if( ( ( Edge* )graphEdge ) -> weight == ... else */
9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* for( i = 0; i < s; i ++ ) */
9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvClearGraph( hlpGraph );
9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvClearGraph( graph );
9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvRestoreMemStoragePos( storage, &storagePos );
9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return change;
9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} /* oneStep */
9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// function initCorr fills correspondence array with initial values
9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      corr                - pointer to correspondence array for this line
9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      width               -  width of image line in pixels
9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      maxPixelDifference  - maximum value of difference between the same
9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            point painted on two images
9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid initCorr( int* corr, int width, int maxPixelDifference )
9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int pixelDifferenceRange = maxPixelDifference * 2 + 1;
9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < width; i ++ )
9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        corr[ i ] = i % pixelDifferenceRange - maxPixelDifference;
9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} /* initCorr */
10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// function oneLineCorr fully computes one line of images
10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      leftLine                - pointer to the left image line
10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      rightLine               - pointer to the right image line
10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      corr                    - pointer to the correspondence array for one
10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                                line
10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      mem                     - pointer to memory allocated by allocTempMem
10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                                function
10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      vertices                - pointer to memory allocated by allocTempMem
10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                                function
10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      width                   - width of image line in pixels
10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      maxPixelDifference      - maximum value of pixel differences in pixels
10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      storage                 - pointer to CvMemStorage struct which
10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                                contains memory storage
10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid oneLineCorr( unsigned char* leftLine,
10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  unsigned char* rightLine,
10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  int* corr,
10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  int* mem,
10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  int* vertices,
10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  int width,
10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  int maxPixelDifference,
10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  CvMemStorage* storage )
10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int result = 1;
10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int count = 0;
10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j;
10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    initCorr( corr, width, maxPixelDifference );
10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( result )
10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        result = 0;
10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = - maxPixelDifference; i < maxPixelDifference; i ++ )
10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = i + 1; j <= maxPixelDifference; j ++ )
10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            result += (int)oneStep( leftLine,
10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               rightLine,
10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               i,
10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               j,
10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               corr,
10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               width,
10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               mem,
10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               vertices,
10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               storage );
10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } /* for( j = i + 1; j < width; j ++ ) */
10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        count ++;
10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( count > /*0*//*1*/2 ) {
10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* while( result ) */
10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} /* oneLineCorr */
10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// function allLinesCorr computes all lines on the images
10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      leftImage           - pointer to the left image
10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      leftLineStep        - size of line on the left image in bytes
10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      rightImage          - pointer to the right image
10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      rightLineStep       - size of line on the right image in bytes
10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      width               - width of line in pixels
10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      height              - height of image in pixels
10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      corr                - pointer to correspondence array for all lines
10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      maxPixelDifference  - maximum value of difference between the same
10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            point painted on two images
10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      storage             - pointer to CvMemStorage which contains memory
10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            storage
10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid allLinesCorr( unsigned char* leftImage,
10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int leftLineStep,
10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   unsigned char* rightImage,
10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int rightLineStep,
10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int width,
10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int height,
10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int* corr,
10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int maxPixelDifference,
10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   CvMemStorage* storage )
10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned char* leftLine = leftImage;
10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned char* rightLine = rightImage;
10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* mem;
10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* vertices;
10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    allocTempMem( &mem,
10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  &vertices,
10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  width );
10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < height; i ++ )
10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        oneLineCorr( leftLine,
10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     rightLine,
10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     corr + i * width,
10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     mem,
10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     vertices,
10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     width,
10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     maxPixelDifference,
10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     storage );
10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        leftLine += leftLineStep;
10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        rightLine += rightLineStep;
11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } /* for( i = 0; i < height; i ++ ) */
11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    freeTempMem( &mem,
11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                 &vertices );
11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} /* allLinesCorr */
11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This function produces morphing of two images into one image, which includes morphed
11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// image or depth map
11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      _leftImage              - pointer to left image
11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      _leftLineStep           - size of line on left image in bytes
11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      _rightImage             - pointer to right image
11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      _rightLineStep          - size of line on right image in bytes
11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      _resultImage            - pointer to result morphed image
11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      _resultLineStep         - size of line on result image in bytes
11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      _corrArray              - pointer to array with correspondences
11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      _numCorrArray           - pointer to array with numbers correspondeces on each line
11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      width                   - width of images
11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      height                  - height of images
11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      alpha                   - position of virtual camera ( 0 corresponds to left image, 1 - to right one )
11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      imageNeed               - defines your wishes. if you want to see normal morphed image you have to set
11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                                this parameter to morphNormalImage ( this is default value ), else if you want
11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                                to see depth map you have to set this parameter to morphDepthMap and set the
11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                                next parameter ( maxPixelDifference ) to real value
11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      maxPixelDifference      - maximum value of pixel difference on two images
11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CCvGraphCutMorpher::Morph( unsigned char* _leftImage,
11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int _leftLineStep,
11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            unsigned char* _rightImage,
11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int _rightLineStep,
11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            unsigned char* _resultImage,
11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int _resultLineStep,
11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int* _corrArray,
11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int width,
11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int height,
11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float alpha,
11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            morphImageType imageNeed,
11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int maxDifference
11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn          )
11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned char* leftArray    = _leftImage;
11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned char* middleArray  = _resultImage;
11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned char* rightArray   = _rightImage;
11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int leftLineSize            = _leftLineStep;
11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int middleLineSize          = _resultLineStep;
11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int rightLineSize           = _rightLineStep;
11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int lineNumber;
11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned char* leftTemp;
11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned char* middleTemp;
11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned char* rightTemp;
11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int leftPixel;
11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int prevLeftPixel;
11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int middlePixel;
11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int prevMiddlePixel;
11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int rightPixel;
11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int prevRightPixel;
11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int leftPixel3;
11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int middlePixel3;
11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int rightPixel3;
11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int j;
11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int tempIndex;
11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* result;
11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int number;
11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float alpha1        = 1.0f - alpha;
11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( lineNumber = 0; lineNumber < height; lineNumber ++ )
11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        leftTemp    = leftArray + leftLineSize * lineNumber;
11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        middleTemp  = middleArray + middleLineSize * lineNumber;
11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        rightTemp   = rightArray + rightLineSize * lineNumber;
11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        memset( ( void* )middleTemp, 0, middleLineSize );
11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        result = _corrArray + width * lineNumber;
11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        number = width;
11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prevLeftPixel   = 0;
11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prevRightPixel  = prevLeftPixel + result[ 0 ];
11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( prevRightPixel >= width ) {
11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prevRightPixel = width - 1;
11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if ( prevRightPixel < 0 ) {
11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prevRightPixel = 0;
11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prevMiddlePixel =
11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            (int)( prevLeftPixel * alpha1 + prevRightPixel * alpha );
11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < number - 1; i ++ )
11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            leftPixel       = i;
11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            rightPixel      = i + result[ i ];
11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( rightPixel >= width ) {
11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rightPixel = width - 1;
11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( rightPixel < 0 ) {
11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rightPixel = 0;
11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            middlePixel     =
11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (int)( leftPixel * alpha1 + rightPixel * alpha );
11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            leftPixel3      = leftPixel * 3;
11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            middlePixel3    = middlePixel * 3;
12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            rightPixel3     = rightPixel * 3;
12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( imageNeed == morphDepthMap ) {
12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int t   = leftPixel - rightPixel + maxDifference;
12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t       = t < 0 ? -t : t;
12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t       = t * 255 / maxDifference / 2;
12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                middleTemp[ middlePixel3 ]      = ( unsigned char )t;
12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                middleTemp[ middlePixel3 + 1 ]  = ( unsigned char )t;
12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                middleTemp[ middlePixel3 + 2 ]  = ( unsigned char )t;
12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } // if( imageNeed == morphDepthMap )
12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                middleTemp[ middlePixel3 ] =
12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    (unsigned char)( leftTemp[ leftPixel3 ] * alpha1
12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    + rightTemp[ rightPixel3 ] * alpha );
12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                middleTemp[ middlePixel3 + 1 ] =
12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    (unsigned char)( leftTemp[ leftPixel3 + 1 ] * alpha1
12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    + rightTemp[ rightPixel3 + 1 ] * alpha );
12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                middleTemp[ middlePixel3 + 2 ] =
12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    (unsigned char)( leftTemp[ leftPixel3 + 2 ] * alpha1
12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    + rightTemp[ rightPixel3 + 2 ] * alpha );
12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( middlePixel - prevMiddlePixel > 1 ) // occlusion
12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( leftPixel - prevLeftPixel > 1 )
12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int LenSrc  = leftPixel - prevLeftPixel - 2;
12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int LenDest = middlePixel - prevMiddlePixel - 1;
12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( j = prevMiddlePixel + 1; j < middlePixel; j ++ )
12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            tempIndex   = prevLeftPixel + 1 + LenSrc *
12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                ( j - prevMiddlePixel - 1 ) / LenDest;
12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            middleTemp[ j * 3 ]     =
12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                leftTemp[ tempIndex * 3 ];
12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            middleTemp[ j * 3 + 1 ] =
12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                leftTemp[ tempIndex * 3 + 1 ];
12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            middleTemp[ j * 3 + 2 ] =
12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                leftTemp[ tempIndex * 3 + 2 ];
12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    } // if( leftPixel - prevLeftPixel > 1 )
12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int LenSrc  = rightPixel - prevRightPixel - 2;
12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int LenDest = middlePixel - prevMiddlePixel - 1;
12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( j = prevMiddlePixel + 1; j < middlePixel; j ++ )
12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            tempIndex   = prevRightPixel + 1 + LenSrc *
12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                ( j - prevMiddlePixel - 1 ) / LenDest;
12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            middleTemp[ j * 3 ]     =
12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                rightTemp[ tempIndex * 3 ];
12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            middleTemp[ j * 3 + 1 ] =
12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                rightTemp[ tempIndex * 3 + 1 ];
12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            middleTemp[ j * 3 + 2 ] =
12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                rightTemp[ tempIndex * 3 + 2 ];
12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    } // if( leftPixel - prevLeftPixel > 1 ) else
12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                } // if( middlePixel - prevMiddlePixel > 1 )
12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            } // if( imageNeed == morphDepthMap ) else
12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( middlePixel > prevMiddlePixel ) {
12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( leftPixel > prevLeftPixel )
12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prevLeftPixel   = leftPixel;
12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( rightPixel > prevRightPixel )
12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prevRightPixel  = rightPixel;
12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                prevMiddlePixel = middlePixel;
12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        } // for( i = number - 1; i >= 0; i -- )
12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } // for( lineNumber = 0; lineNumber < LeftImage -> m_Raster -> GetHeight() )
12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // Morph
12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool  CCvGraphCutMorpher::OnCalculateStereo()
12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize imageSizeLeft = GetImageSize( m_left_img ),
12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           imageSizeRight = GetImageSize( m_right_img );
12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ( imageSizeLeft.width != imageSizeRight.width )
12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        || ( imageSizeLeft.height != imageSizeRight.height ) )
12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return false;
12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( m_corr ) {
12866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        free( m_corr );
12876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_corr = NULL;
12886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_corr = ( int* ) malloc( m_left_img -> width
12906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        * m_left_img -> height
12916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        * sizeof( int ) );
12926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !m_storage ) {
12946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_storage = cvCreateMemStorage( 0 );
12956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_isStorageAllocated = true;
12966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Find correspondence for full image and store it to corr array
12986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    allLinesCorr( ( unsigned char* )m_left_img -> imageData,
12996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  m_left_img -> widthStep,
13006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  ( unsigned char* )m_right_img -> imageData,
13016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  m_right_img -> widthStep,
13026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  m_left_img -> width,
13036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  m_left_img -> height,
13046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  m_corr,
13056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  m_maxPixelDifference,
13066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  m_storage );
13076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_isStereoReady = true;
13096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return true;
13116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool  CCvGraphCutMorpher::OnCalculateVirtualImage()
13146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
13156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Output image to ResultImage window
13166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Morph( ( unsigned char* )m_left_img -> imageData,
13176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_left_img ->widthStep,
13186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           ( unsigned char* )m_right_img -> imageData,
13196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_right_img -> widthStep,
13206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           ( unsigned char* )m_virtual_img -> imageData,
13216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_virtual_img -> widthStep,
13226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_corr,
13236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_left_img -> width,
13246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_left_img -> height,
13256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_pan );
13266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_isVirtualImageReady = true;
13286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return true;
13306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool  CCvGraphCutMorpher::OnCalculateDisparity()
13336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
13346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Morph( ( unsigned char* )m_left_img -> imageData,
13356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_left_img ->widthStep,
13366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           ( unsigned char* )m_right_img -> imageData,
13376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_right_img -> widthStep,
13386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           ( unsigned char* )m_disparity_img -> imageData,
13396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_disparity_img -> widthStep,
13406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_corr,
13416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_left_img -> width,
13426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_left_img -> height,
13436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_pan,
13446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           morphDepthMap,
13456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_maxPixelDifference );
13466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return true;
13486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool  CCvGraphCutMorpher::OnCalculateDisparityImage()
13516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
13526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Morph( ( unsigned char* )m_left_img -> imageData,
13536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_left_img ->widthStep,
13546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           ( unsigned char* )m_right_img -> imageData,
13556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_right_img -> widthStep,
13566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           ( unsigned char* )m_disparity_img -> imageData,
13576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_disparity_img -> widthStep,
13586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_corr,
13596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_left_img -> width,
13606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_left_img -> height,
13616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_pan,
13626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           morphDepthMap,
13636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           m_maxPixelDifference );
13646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return true;
13666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCCvGraphCutMorpher::CCvGraphCutMorpher()
13696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
13706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_maxPixelDifference = MAX_DIFFERENCE;
13716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_corr = 0;
13726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_isStereoReady = false;
13736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_isVirtualImageReady = false;
13746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_isDisparityReady = false;
13756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_storage = NULL;
13766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_isStorageAllocated = false;
13776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
13806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file */
1382