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