+++ /dev/null
-/*M///////////////////////////////////////////////////////////////////////////////////////
-//
-// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
-//
-// By downloading, copying, installing or using the software you agree to this license.
-// If you do not agree to this license, do not download, install,
-// copy or use the software.
-//
-//
-// Intel License Agreement
-// For Open Source Computer Vision Library
-//
-// Copyright (C) 2000, Intel Corporation, all rights reserved.
-// Third party copyrights are property of their respective owners.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// * Redistribution's of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// * Redistribution's in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-//
-// * The name of Intel Corporation may not be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// This software is provided by the copyright holders and contributors "as is" and
-// any express or implied warranties, including, but not limited to, the implied
-// warranties of merchantability and fitness for a particular purpose are disclaimed.
-// In no event shall the Intel Corporation or contributors be liable for any direct,
-// indirect, incidental, special, exemplary, or consequential damages
-// (including, but not limited to, procurement of substitute goods or services;
-// loss of use, data, or profits; or business interruption) however caused
-// and on any theory of liability, whether in contract, strict liability,
-// or tort (including negligence or otherwise) arising in any way out of
-// the use of this software, even if advised of the possibility of such damage.
-//
-//M*/
-
-#include "_cvaux.h"
-
-#if 0
-
-//#include "windows.h"
-
-//#define ALPHA_EXPANSION
-
-#ifndef ALPHA_EXPANSION
- #define ALPHA_BETA_EXCHANGE
-#endif
-
-#define MAX_LABEL 20
-
-#define CV_MODULE(xxx) \
- ( (xxx) < 0 ? -(xxx) : (xxx) )
-
-#define CV_MAX3(xxx1,xxx2,xxx3) \
- ( (xxx1) > (xxx2) && (xxx1) > (xxx3) ? (xxx1) : \
- (xxx2) > (xxx3) ? (xxx2) : (xxx3) )
-
-#define CV_MIN2(xxx1,xxx2) \
- ( (xxx1) < (xxx2) ? (xxx1) : (xxx2) )
-
-#define getSizeForGraph(xxxType) \
- ( sizeof(xxxType) < 8 ? 8 : sizeof(xxxType) + 4 - sizeof(xxxType) % 4 )
-
-#define INT_INFINITY 1000000000
-#define MAX_DIFFERENCE 10
-
-
-// struct Vertex is used for storing vertices of graph
-// coord - coordinate corresponding pixel on the real image line
-struct Vertex
-{
- CvGraphVtx vtx;
- int coord;
-};
-
-// struct Edge is used for storing edges of graph
-// weight - weight of the edge ( maximum flow via the edge )
-// flow - current flow via the edge
-// srcVtx - coordinate of source vertex on the real image line
-// destVtx - coordinate of destination vertex on the real image line
-struct Edge
-{
- CV_GRAPH_EDGE_FIELDS()
- int weight;
- int flow;
- int srcVtx;
- int destVtx;
-};
-
-// function vFunc is energy function which determines the difference
-// between two labels ( alpha and beta )
-// alpha - label number one
-// beta - label number two
-inline int vFunc( int alpha, int beta )
-{
- if( alpha == beta )
- return 0;
- else
- return /*1*//*5*/10;
-}
-
-// function dFunc is energy function which determines energy of interaction
-// between pixel ( having coordinate xCoord ) and label
-// leftLine - line of left image
-// rightLine - line of right image
-// xCoord - coordinate of pixel on the left image
-// label - label corresponding to the pixel
-// width - width of the image line in pixels
-inline int dFunc( unsigned char* leftLine,
- unsigned char* rightLine,
- int xCoord,
- int label,
- int width)
-{
- assert( xCoord >= 0 && xCoord < width );
- int r, g, b;
- int yCoord = xCoord + label;
-
- if( yCoord >= width )
- yCoord = width;
- if( yCoord < 0 )
- yCoord = 0;
-
- r = leftLine[ 3 * xCoord ] - rightLine[ 3 * yCoord ];
- g = leftLine[ 3 * xCoord + 1 ] - rightLine[ 3 * yCoord + 1 ];
- b = leftLine[ 3 * xCoord + 2 ] - rightLine[ 3 * yCoord + 2 ];
-
- r = CV_MODULE( r );
- g = CV_MODULE( g );
- b = CV_MODULE( b );
-
- return CV_MAX3( r, g, b );
-}
-
-// function allocTempMem allocates all temporary memory needed for work
-// of some function
-// memPtr - pointer to pointer to the large block of memory
-// verticesPtr - pointer to pointer to block of memory for
-// temporary storing vertices
-// width - width of line in pixels
-void allocTempMem( int** memPtr,
- int** verticesPtr,
- int width )
-{
- int* tempPtr = ( int* ) malloc( ( width + 2 ) * 7 * sizeof( int ) );
- *verticesPtr = tempPtr;
- *memPtr = *verticesPtr + width + 2;
-}
-
-// function freeTempMem frees all allocated by allocTempMem function memory
-// memPtr - pointer to pointer to the large block of memory
-// verticesPtr - pointer to pointer to block of memory for
-// temporary storing vertices
-void freeTempMem( int** memPtr,
- int** verticesPtr )
-{
- free( ( void* )( *verticesPtr ) );
- *verticesPtr = NULL;
- *memPtr = NULL;
-}
-
-// function makeGraph creates initial graph to find maximum flow in it
-// graphPtr - pointer to pointer to CvGraph structure to be filled
-// leftLine - pointer to the left image line
-// rightLine - pointer to the right image line
-// alpha - label number one for doing exchange
-// beta - label number two for doing exchange
-// corr - pointer to array of correspondences ( each element
-// of array includes disparity of pixel on right image
-// for pixel each on left image ). This pointer direct
-// to correspondence ofr one line only
-// width - width of image lines in pixels
-// storage - pointer to CvMemStorage structure which contains
-// memory storage
-void makeGraph( CvGraph** graphPtr,
- unsigned char* leftLine,
- unsigned char* rightLine,
- int alpha,
- int beta,
- int* corr,
- int width,
- CvMemStorage* storage )
-{
- int i;
-
- if( *graphPtr ) {
- cvClearGraph( *graphPtr );
- }
- /*else {*/
- *graphPtr = cvCreateGraph( CV_SEQ_KIND_GRAPH | CV_GRAPH_FLAG_ORIENTED,
- sizeof( CvGraph ),
- getSizeForGraph( Vertex ),
- getSizeForGraph( Edge ),
- storage );
- /*}*/
-
- CvGraph* graph = *graphPtr;
-
- #ifdef ALPHA_BETA_EXCHANGE
-
- CvGraphVtx* newVtxPtr;
- for( i = 0; i < width; i ++ )
- {
- if( corr[i] == alpha || corr[i] == beta ) {
- cvGraphAddVtx( graph, NULL, &newVtxPtr );
- ( ( Vertex* )newVtxPtr ) -> coord = i;
- }
- } /* for( i = 0; i < width; i ++ ) */
- cvGraphAddVtx( graph, NULL, &newVtxPtr );
- if( newVtxPtr )
- ( ( Vertex* )newVtxPtr ) -> coord = -2; /* adding alpha vertex */
- cvGraphAddVtx( graph, NULL, &newVtxPtr );
- if( newVtxPtr )
- ( ( Vertex* )newVtxPtr ) -> coord = -1; /* adding beta vertex */
-
- int alphaVtx = graph -> total - 2;
- int betaVtx = graph -> total - 1;
- CvGraphEdge* newEdgePtr;
- CvGraphVtx* vtxPtr;
- if( graph -> total > 2 )
- {
- for( i = 0; i < alphaVtx; i ++ )
- {
- vtxPtr = cvGetGraphVtx( graph, i );
-
- /* adding edge oriented from alpha vertex to current vertex */
- cvGraphAddEdge( graph, alphaVtx, i, NULL, &newEdgePtr );
- ( ( Edge* )newEdgePtr ) -> weight = dFunc( leftLine,
- rightLine,
- ( ( Vertex* )vtxPtr ) -> coord,
- alpha,
- width );
- ( ( Edge* )newEdgePtr ) -> flow = 0;
- if( i != 0 ) {
- CvGraphVtx* tempVtxPtr = cvGetGraphVtx( graph, i - 1 );
- /* if vertices are neighbours */
- if( ( ( Vertex* )tempVtxPtr ) -> coord + 1 ==
- ( ( Vertex* )vtxPtr ) -> coord )
- {
- ( ( Edge* )newEdgePtr ) -> weight +=
- vFunc( corr[ ( ( Vertex* )tempVtxPtr ) -> coord ],
- alpha );
- /* adding neighbour edge oriented from current vertex
- to the previous one */
- CvGraphEdge* tempEdgePtr;
- cvGraphAddEdge( graph, i, i - 1, NULL, &tempEdgePtr );
- ( ( Edge* )tempEdgePtr ) -> weight = vFunc( alpha, beta );
- ( ( Edge* )tempEdgePtr ) -> flow = 0;
- ( ( Edge* )tempEdgePtr ) -> srcVtx =
- ( ( Vertex* )vtxPtr ) -> coord;
- ( ( Edge* )tempEdgePtr ) -> destVtx =
- ( ( Vertex* )tempVtxPtr ) -> coord;
- }
- } /* if( i != 0 ) */
- if( i != alphaVtx - 1 ) {
- CvGraphVtx* tempVtxPtr = cvGetGraphVtx( graph, i + 1 );
- /* if vertices are neighbours */
- if( ( ( Vertex* )tempVtxPtr ) -> coord - 1 ==
- ( ( Vertex* )vtxPtr ) -> coord )
- {
- ( ( Edge* )newEdgePtr ) -> weight +=
- vFunc( corr[ ( ( Vertex* )tempVtxPtr ) -> coord ],
- alpha );
- /* adding neighbour edge oriented from current vertex
- to the next one */
- CvGraphEdge* tempEdgePtr;
- cvGraphAddEdge( graph, i, i + 1, NULL, &tempEdgePtr );
- ( ( Edge* )tempEdgePtr ) -> weight = vFunc( alpha, beta );
- ( ( Edge* )tempEdgePtr ) -> flow = 0;
- ( ( Edge* )tempEdgePtr ) -> srcVtx =
- ( ( Vertex* )vtxPtr ) -> coord;
- ( ( Edge* )tempEdgePtr ) -> destVtx =
- ( ( Vertex* )tempVtxPtr ) -> coord;
- }
- } /* if( i != alphaVtx - 1 ) */
- ( ( Edge* )newEdgePtr ) -> flow = 0;
- ( ( Edge* )newEdgePtr ) -> srcVtx = -1; /* source vertex is alpha
- vertex */
- ( ( Edge* )newEdgePtr ) -> destVtx = ( ( Vertex* )vtxPtr ) -> coord;
-
- /* adding edge oriented from current vertex to beta vertex */
- cvGraphAddEdge( graph, i, betaVtx, NULL, &newEdgePtr );
- ( ( Edge* )newEdgePtr ) -> weight = dFunc( leftLine,
- rightLine,
- ( ( Vertex* )vtxPtr ) -> coord,
- beta,
- width );
- ( ( Edge* )newEdgePtr ) -> flow = 0;
- if( i != 0 ) {
- CvGraphVtx* tempVtxPtr = cvGetGraphVtx( graph, i - 1 );
- /* if vertices are neighbours */
- if( ( ( Vertex* )tempVtxPtr ) -> coord + 1 ==
- ( ( Vertex* )vtxPtr ) -> coord )
- {
- ( ( Edge* )newEdgePtr ) -> weight +=
- vFunc( corr[ ( ( Vertex* )tempVtxPtr ) -> coord ],
- beta );
- }
- } /* if( i != 0 ) */
- if( i != alphaVtx - 1 ) {
- CvGraphVtx* tempVtxPtr = cvGetGraphVtx( graph, i + 1 );
- /* if vertices are neighbours */
- if( ( ( Vertex* )tempVtxPtr ) -> coord - 1 ==
- ( ( Vertex* )vtxPtr ) -> coord )
- {
- ( ( Edge* )newEdgePtr ) -> weight +=
- vFunc( corr[ ( ( Vertex* )tempVtxPtr ) -> coord ],
- beta );
- }
- } /* if( i != alphaVtx - 1 ) */
- ( ( Edge* )newEdgePtr ) -> flow = 0;
- ( ( Edge* )newEdgePtr ) -> srcVtx =
- ( ( Vertex* )vtxPtr ) -> coord;
- ( ( Edge* )newEdgePtr ) -> destVtx = -2; /* destination vertex is
- beta vertex */
-
- } /* for( i = 0; i < graph -> total - 2; i ++ ) */
-
- } /* if( graph -> total > 2 ) */
-
- #endif /* #ifdef ALPHA_BETA_EXCHANGE */
-
- #ifdef ALPHA_EXPANSION
- #endif /* #ifdef ALPHA_EXPANSION */
-
-} /* makeGraph */
-
-// function makeHelpGraph creates help graph using initial graph
-// graph - pointer to initial graph ( represented by CvGraph
-// structure )
-// hlpGraphPtr - pointer to pointer to new help graph
-// storage - pointer to CvStorage structure
-// mem - pointer to memory allocated by allocTempMem function
-// vertices - pointer to memory allocated by allocTempMem function
-// verticesCountPtr- pointer to value containing number of vertices
-// in vertices array
-// width - width of image line in pixels
-int makeHelpGraph( CvGraph* graph,
- CvGraph** hlpGraphPtr,
- CvMemStorage* storage,
- int* mem,
- int* vertices,
- int* verticesCountPtr,
- int width )
-{
- int u, v;
- int* order = mem;
- int* lengthArr = order + width + 2;
- int s = graph -> total - 2; /* source vertex */
- int t = graph -> total - 1; /* terminate vertex */
- int orderFirst;
- int orderCount;
- int &verticesCount = *verticesCountPtr;
- CvGraph* hlpGraph;
-
- if( *hlpGraphPtr ) {
- cvClearGraph( *hlpGraphPtr );
- }
- else {
- *hlpGraphPtr = cvCreateGraph( CV_SEQ_KIND_GRAPH |
- CV_GRAPH_FLAG_ORIENTED,
- sizeof( CvGraph ),
- getSizeForGraph( Vertex ),
- getSizeForGraph( Edge ),
- storage );
- }
-
- hlpGraph = *hlpGraphPtr;
-
- /* initialization */
- for( u = 0; u < graph -> total; u ++ )
- {
- lengthArr[ u ] = INT_INFINITY;
- cvGraphAddVtx( hlpGraph, NULL, NULL );
- } /* for( u = 0; u < graph -> total - 1; u ++ ) */
-
- orderFirst = 0;
- orderCount = 0;
- verticesCount = 0;
- lengthArr[ s ] = 0;
-
- /* add vertex s to order */
- order[ orderCount ] = s;
- orderCount ++;
-
- while( orderCount != orderFirst )
- {
- /* getting u from order */
- u = order[ orderFirst ];
- orderFirst ++;
-
- /* adding u to vertex array */
- vertices[ verticesCount ] = u;
- verticesCount ++;
-
- int ofs;
- CvGraphVtx* graphVtx = cvGetGraphVtx( graph, u );
-
- /* processing all vertices outgoing from vertex u */
- CvGraphEdge* graphEdge = graphVtx -> first;
- while( graphEdge )
- {
- int tempVtxIdx = cvGraphVtxIdx( graph, graphEdge -> vtx[1] );
- ofs = tempVtxIdx == u;
- if( !ofs )
- {
- v = tempVtxIdx;
-
- CvGraphEdge* tempGraphEdge = cvFindGraphEdge( graph, u, v );
- if( ( lengthArr[ u ] < lengthArr[ v ] )
- && ( lengthArr[ v ] <= lengthArr[ t ] )
- && ( ( ( Edge* )tempGraphEdge ) -> flow <
- ( ( Edge* )tempGraphEdge ) -> weight ) )
- {
- if( lengthArr[ v ] == INT_INFINITY )
- {
- /* adding vertex v to order */
- order[ orderCount ] = v;
- orderCount ++;
-
- lengthArr[ v ] = lengthArr[ u ] + 1;
- CvGraphEdge* tempGraphEdge2;
-
- cvGraphAddEdge( hlpGraph, u, v, NULL, &tempGraphEdge2 );
- ( ( Edge* )tempGraphEdge2 ) -> flow = 0;
-
- ( ( Edge* )tempGraphEdge2 ) -> weight =
- ( ( Edge* )tempGraphEdge ) -> weight -
- ( ( Edge* )tempGraphEdge ) -> flow;
-
- } /* if( length[ v ] == INT_INFINITY ) */
-
- } /* if( ( lengthArr[ u ] < lengthArr[ v ] ) ... */
-
- } /* if( !ofs ) */
-
- graphEdge = graphEdge -> next[ ofs ];
-
- } /* while( graphEdge ) */
-
- /* processing all vertices incoming to vertex u */
- graphEdge = graphVtx -> first;
- while( graphEdge )
- {
- int tempVtxIdx = cvGraphVtxIdx( graph, graphEdge -> vtx[1] );
- ofs = tempVtxIdx == u;
- if( ofs )
- {
- tempVtxIdx = cvGraphVtxIdx( graph, graphEdge -> vtx[0] );
- v = tempVtxIdx;
-
- CvGraphEdge* tempGraphEdge = cvFindGraphEdge( graph, v, u );
- if( ( lengthArr[ u ] < lengthArr[ v ] )
- && ( lengthArr[ v ] <= lengthArr[ t ] )
- && ( ( ( Edge* )tempGraphEdge ) -> flow > 0 ) )
- {
- if( lengthArr[ v ] == INT_INFINITY )
- {
- /* adding vertex v to order */
- order[ orderCount ] = v;
- orderCount ++;
-
- lengthArr[ v ] = lengthArr[ u ] + 1;
- CvGraphEdge* tempGraphEdge3 = cvFindGraphEdge( hlpGraph, u, v );
-
- if( tempGraphEdge3 == NULL ||
- ( ( Edge* )tempGraphEdge3 ) -> weight == 0 )
- {
- CvGraphEdge* tempGraphEdge2;
- cvGraphAddEdge( hlpGraph, u, v, NULL,
- &tempGraphEdge2 );
- ( ( Edge* )tempGraphEdge2 ) -> flow = 0;
- ( ( Edge* )tempGraphEdge2 ) -> weight = 0;
- } /* if( tempGraphEdge3 == NULL || ... */
-
- ( ( Edge* )tempGraphEdge3 ) -> weight +=
- ( ( Edge* )tempGraphEdge ) -> flow;
-
- } /* if( length[ v ] == INT_INFINITY ) */
-
- } /* if( ( lengthArr[ u ] < lengthArr[ v ] ) ... */
-
- } /* if( ofs ) */
-
- graphEdge = graphEdge -> next[ ofs ];
-
- } /* while( graphEdge ) */
-
- } /* while( orderCount != orderFirst ) */
-
- int i;
- for( i = 0; i < hlpGraph -> total - 2; i ++ )
- {
- CvGraphVtx* hlpGraphVtxTemp = cvGetGraphVtx( hlpGraph, i );
- if( hlpGraphVtxTemp ) {
- if( !hlpGraphVtxTemp -> first ) {
- cvGraphRemoveVtxByPtr( hlpGraph, hlpGraphVtxTemp );
- }
- }
- } /* for( i = 0; i < hlpGraph -> total - 2; i ++ ) */
-
- return lengthArr[ t ];
-
-} /* makeHelpGraph */
-
-// function makePseudoMaxFlow increases flow in graph by using hlpGraph
-// graph - pointer to initial graph
-// hlpGraph - pointer to help graph
-// vertices - pointer to vertices array
-// verticesCount - number of vertices in vertices array
-// mem - pointer to memory allocated by allocTempMem function
-// width - width of image line in pixels
-void makePseudoMaxFlow( CvGraph* graph,
- CvGraph* hlpGraph,
- int* vertices,
- int verticesCount,
- int* mem,
- int width )
-{
- int stekCount;
- int orderFirst;
- int orderCount;
- int i;
- int v, u;
- int* stek = mem;
- int* order = stek + width + 2;
- int* incomFlow = order + width + 2;
- int* outgoFlow = incomFlow + width + 2;
- int* flow = outgoFlow + width + 2;
- int* cargo = flow+ width + 2;
- int s = graph -> total - 2; /* source vertex */
- int t = graph -> total - 1; /* terminate vertex */
- int realVerticesCount = verticesCount;
-
- stekCount = 0;
-
- for( i = 0; i < verticesCount; i ++ )
- {
- v = vertices[ i ];
-
- incomFlow[ v ] = outgoFlow[ v ] = 0;
-
- if( v == s ) {
- incomFlow[ v ] = INT_INFINITY;
- } /* if( v == s ) */
- else {
- CvGraphVtx* hlpGraphVtx = cvGetGraphVtx( hlpGraph, v );
- CvGraphEdge* hlpGraphEdge = hlpGraphVtx -> first;
- int ofs;
-
- while( hlpGraphEdge )
- {
- int vtxIdx = cvGraphVtxIdx( hlpGraph,
- hlpGraphEdge -> vtx[1] );
- ofs = vtxIdx == v;
-
- if( ofs )
- {
- incomFlow[ v ] += ( ( Edge* )hlpGraphEdge ) -> weight;
- } /* if( ofs ) */
-
- hlpGraphEdge = hlpGraphEdge -> next[ ofs ];
- } /* while( hlpGraphEdge ) */
-
- } /* if( v == s ) else */
-
- if( v == t ) {
- outgoFlow[ v ] = INT_INFINITY;
- } /* if( v == t ) */
- else {
- CvGraphVtx* hlpGraphVtx = cvGetGraphVtx( hlpGraph, v );
- CvGraphEdge* hlpGraphEdge = hlpGraphVtx -> first;
- int ofs;
-
- while( hlpGraphEdge )
- {
- int vtxIdx = cvGraphVtxIdx( hlpGraph,
- hlpGraphEdge -> vtx[1] );
- ofs = vtxIdx == v;
-
- if( !ofs )
- {
- outgoFlow[ v ] += ( ( Edge* )hlpGraphEdge ) -> weight;
- } /* if( ofs ) */
-
- hlpGraphEdge = hlpGraphEdge -> next[ ofs ];
- } /* while( hlpGraphEdge ) */
-
- } /* if( v == t ) else */
-
- flow[ v ] = CV_MIN2( incomFlow[ v ], outgoFlow[ v ] );
-
- if( !flow[ v ] ) {
- stek[ stekCount ] = v;
- stekCount ++;
- } /* if( !flow[ v ] ) */
-
- } /* for( i = 0; i < verticesCount; i ++ ) */
-
- for( i = 0; i < verticesCount; i ++ )
- {
- v = vertices[ i ];
- cargo[ v ] = 0;
- } /* for( i = 0; i < verticesCount; i ++ ) */
-
- while( realVerticesCount > 2 )
- {
- /* deleting all vertices included in stek */
- while( stekCount )
- {
- v = stek[ stekCount - 1 ];
- stekCount --;
-
- /* deleting edges incoming to v and outgoing from v */
- int ofs;
- CvGraphVtx* hlpGraphVtx = cvGetGraphVtx( hlpGraph, v );
- CvGraphEdge* hlpGraphEdge;
- if( hlpGraphVtx ) {
- hlpGraphEdge = hlpGraphVtx -> first;
- }
- else {
- hlpGraphEdge = NULL;
- }
- while( hlpGraphEdge )
- {
- CvGraphVtx* hlpGraphVtx2 = hlpGraphEdge -> vtx[ 1 ];
- int hlpGraphVtxIdx2 = cvGraphVtxIdx( hlpGraph,
- hlpGraphVtx2 );
- ofs = hlpGraphVtxIdx2 == v;
-
- if( ofs )
- {
- /* hlpGraphEdge is incoming edge */
- CvGraphVtx* hlpGraphVtx3 = hlpGraphEdge -> vtx[0];
- u = cvGraphVtxIdx( hlpGraph,
- hlpGraphVtx3 );
- outgoFlow[ u ] -= ( ( Edge* )hlpGraphEdge ) -> weight
- - ( ( Edge* )hlpGraphEdge ) -> flow;
- cvGraphRemoveEdgeByPtr( hlpGraph,
- hlpGraphVtx3,
- hlpGraphVtx2 );
- if( flow[ u ] != 0 ) {
- flow[ u ] = CV_MIN2( incomFlow[u], outgoFlow[u] );
- if( flow[ u ] == 0 ) {
- stek[ stekCount ] = u;
- stekCount ++;
- }
- }
- } /* if( ofs ) */
- else
- {
- /* hlpGraphEdge is outgoing edge */
- CvGraphVtx* hlpGraphVtx3 = hlpGraphEdge -> vtx[1];
- int u = cvGraphVtxIdx( hlpGraph,
- hlpGraphVtx3 );
- incomFlow[ u ] -= ( ( Edge* )hlpGraphEdge ) -> weight
- - ( ( Edge* )hlpGraphEdge ) -> flow;
- cvGraphRemoveEdgeByPtr( hlpGraph,
- hlpGraphVtx2,
- hlpGraphVtx3 );
- if( flow[ u ] != 0 ) {
- flow[ u ] = CV_MIN2( incomFlow[u], outgoFlow[u] );
- if( flow[ u ] == 0 ) {
- stek[ stekCount ] = u;
- stekCount ++;
- }
- }
- } /* if( ofs ) else */
-
- hlpGraphEdge = hlpGraphEdge -> next[ ofs ];
-
- } /* while( hlpGraphEdge ) */
-
- /* deleting vertex v */
- cvGraphRemoveVtx( hlpGraph, v );
- realVerticesCount --;
-
- } /* while( stekCount ) */
-
- if( realVerticesCount > 2 ) /* the flow is not max still */
- {
- int p = INT_INFINITY;
- int r = -1;
- CvGraphVtx* graphVtx;
-
- if( realVerticesCount == 3 ) {
- r = r;
- }
- for( i = 0; i < hlpGraph -> total - 2; i ++ )
- {
- graphVtx = cvGetGraphVtx( hlpGraph, i );
- if( graphVtx ) {
- v = cvGraphVtxIdx( hlpGraph, graphVtx );
- if( flow[ v ] < p ) {
- r = v;
- p = flow[ v ];
- }
- }
-
- } /* for( i = 0; i < hlpGraph -> total - 2; i ++ ) */
-
- /* building of size p flow from r to t */
- orderCount = orderFirst = 0;
- order[ orderCount ] = r;
- orderCount ++;
-
- v = order[ orderFirst ];
- orderFirst ++;
-
- cargo[ r ] = p;
- do /* while( v != t ) */
- {
- incomFlow[ v ] -= cargo[ v ];
- outgoFlow[ v ] -= cargo[ v ];
- flow[ v ] -= cargo[ v ];
-
- if( flow[ v ] == 0 ) {
- stek[ stekCount ] = v;
- stekCount ++;
- }
-
- if( v == t ) {
- cargo[ v ] = p;
- }
- else
- {
- int ofs;
- CvGraphVtx* hlpGraphVtx2;
- CvGraphVtx* hlpGraphVtx = cvGetGraphVtx( hlpGraph, v );
- CvGraphEdge* hlpGraphEdge = hlpGraphVtx -> first;
- CvGraphEdge* hlpGraphEdge2 = NULL;
-
- while( hlpGraphEdge && cargo[ v ] > 0 )
- {
- hlpGraphVtx2 = hlpGraphEdge -> vtx[ 1 ];
- u = cvGraphVtxIdx( hlpGraph, hlpGraphVtx2 );
- ofs = u == v;
-
- if( !ofs )
- {
- if( cargo[ u ] == 0 ) {
- order[ orderCount ] = u;
- orderCount ++;
- }
- int delta = ( ( Edge* )hlpGraphEdge ) -> weight
- - ( ( Edge* )hlpGraphEdge ) -> flow;
- delta = CV_MIN2( cargo[ v ], delta );
- ( ( Edge* )hlpGraphEdge ) -> flow += delta;
- cargo[ v ] -= delta;
- cargo[ u ] += delta;
- if( ( ( Edge* )hlpGraphEdge ) -> weight ==
- ( ( Edge* )hlpGraphEdge ) -> flow )
- {
- /* deleting hlpGraphEdge */
- hlpGraphEdge2 = hlpGraphEdge -> next[ ofs ];
- CvGraphEdge* graphEdge =
- cvFindGraphEdge( graph, v, u );
- ( ( Edge* )graphEdge ) -> flow +=
- ( ( Edge* )hlpGraphEdge ) -> flow;
- cvGraphRemoveEdgeByPtr( hlpGraph,
- hlpGraphEdge -> vtx[0],
- hlpGraphEdge -> vtx[1] );
- }
- } /* if( !ofs ) */
-
- if( hlpGraphEdge2 ) {
- hlpGraphEdge = hlpGraphEdge2;
- hlpGraphEdge2 = NULL;
- }
- else {
- hlpGraphEdge = hlpGraphEdge -> next[ ofs ];
- }
- } /* while( hlpGraphEdge && cargo[ v ] > 0 ) */
-
- } /* if( v == t ) else */
-
- v = order[ orderFirst ];
- orderFirst ++;
-
- } while( v != t ); /* do */
-
- /* building of size p flow from s to r */
- orderCount = orderFirst = 0;
- order[ orderCount ] = r;
- orderCount ++;
-
- v = order[ orderFirst ];
- orderFirst ++;
-
- cargo[ r ] = p;
- do /* while( v != s ) */
- {
- if( v != r )
- {
- incomFlow[ v ] -= cargo[ v ];
- outgoFlow[ v ] -= cargo[ v ];
- flow[ v ] -= cargo[ v ];
- if( flow[ v ] == 0 ) {
- stek[ stekCount ] = v;
- stekCount ++;
- }
- } /* if( v != r ) */
-
- if( v == s ) {
- cargo[ v ] = 0;
- } /* if( v == s ) */
- else
- {
- int ofs;
-
- CvGraphVtx* hlpGraphVtx = cvGetGraphVtx( hlpGraph, v );
- CvGraphEdge* hlpGraphEdge = hlpGraphVtx -> first;
- CvGraphEdge* hlpGraphEdge2 = NULL;
- while( hlpGraphEdge && cargo[ v ] > 0 )
- {
- u = cvGraphVtxIdx( hlpGraph,
- hlpGraphEdge -> vtx[ 1 ] );
- ofs = u == v;
-
- if( ofs )
- {
- u = cvGraphVtxIdx( hlpGraph,
- hlpGraphEdge -> vtx[ 0 ] );
-
- if( cargo[ u ] == 0 ) {
- order[ orderCount ] = u;
- orderCount ++;
- }
-
- int delta = ( ( Edge* )hlpGraphEdge ) -> weight
- - ( ( Edge* )hlpGraphEdge ) -> flow;
-
- delta = CV_MIN2( cargo[ v ], delta );
-
- (( ( Edge* )hlpGraphEdge ) -> flow) += delta;
-
- cargo[ v ] -= delta;
- cargo[ u ] += delta;
-
- if( ( ( Edge* )hlpGraphEdge ) -> weight ==
- ( ( Edge* )hlpGraphEdge ) -> flow )
- {
- hlpGraphEdge2 = hlpGraphEdge -> next[ ofs ];
- CvGraphEdge* graphEdge =
- cvFindGraphEdge( graph, u, v );
- ( ( Edge* )graphEdge ) -> flow +=
- ( ( Edge* )hlpGraphEdge ) -> flow;
- cvGraphRemoveEdgeByPtr( hlpGraph,
- hlpGraphEdge -> vtx[0],
- hlpGraphEdge -> vtx[1] );
- }
- } /* if( ofs ) */
-
- if( hlpGraphEdge2 ) {
- hlpGraphEdge = hlpGraphEdge2;
- hlpGraphEdge2 = NULL;
- }
- else {
- hlpGraphEdge = hlpGraphEdge -> next[ ofs ];
- }
- } /* while( hlpGraphEdge && cargo[ v ] > 0 ) */
-
- } /* if( v == s ) else */
-
- v = order[ orderFirst ]; //added
- orderFirst ++; //added
-
- } while( v != s ); /* do */
-
- } /* if( hlpGraph -> total > 2 ) */
-
- } /* while( hlpGraph -> total > 2 ) */
-
-} /* makePseudoMaxFlow */
-
-
-// function oneStep produces one alpha-beta exchange for one line of images
-// leftLine - pointer to the left image line
-// rightLine - pointer to the right image line
-// alpha - label number one
-// beta - label number two
-// corr - pointer to correspondence array for this line
-// width - width of image line in pixels
-// mem - pointer to memory allocated by allocTempMem function
-// vertices - pointer to vertices array allocated by allocTempMem
-// function
-// storage - pointer to CvMemStorage structure
-bool oneStep( unsigned char* leftLine,
- unsigned char* rightLine,
- int alpha,
- int beta,
- int* corr,
- int width,
- int* mem,
- int* vertices,
- CvMemStorage* storage )
-{
- CvGraph* graph = NULL;
- CvGraph* hlpGraph = NULL;
- CvMemStoragePos storagePos;
- int i;
- bool change = false;
- cvSaveMemStoragePos( storage, &storagePos );
-
- int verticesCount;
-
- makeGraph( &graph, leftLine, rightLine, alpha, beta, corr, width, storage );
-
- int s = graph -> total - 2; /* source vertex - alpha vertex */
- //int t = graph -> total - 1; /* terminate vertex - beta vertex */
-
- int length = makeHelpGraph( graph,
- &hlpGraph,
- storage,
- mem,
- vertices,
- &verticesCount,
- width );
- while( length != INT_INFINITY )
- {
- change = true;
- makePseudoMaxFlow( graph,
- hlpGraph,
- vertices,
- verticesCount,
- mem,
- width );
- cvClearGraph( hlpGraph );
- length = makeHelpGraph( graph,
- &hlpGraph,
- storage,
- mem,
- vertices,
- &verticesCount,
- width );
- } /* while( length != INT_INFINITY ) */
-
- int coord;
- CvGraphVtx* graphVtx;
- for( i = 0; i < s; i ++ )
- {
- CvGraphEdge* graphEdge = cvFindGraphEdge( graph, s, i );
-
- if( ( ( Edge* )graphEdge ) -> weight ==
- ( ( Edge* )graphEdge ) -> flow )
- { /* this vertex must have alpha label */
- graphVtx = cvGetGraphVtx( graph, i );
- coord = ( ( Vertex* )graphVtx )-> coord;
- if( corr[ coord ] != alpha ) {
- corr[ coord ] = alpha; //added
- change = true;
- }
- else {
- corr[ coord ] = alpha;
- }
- } /* if( ( ( Edge* )graphEdge ) -> weight == ... */
- else
- { /* this vertex must have beta label */
- graphVtx = cvGetGraphVtx( graph, i );
- coord = ( ( Vertex* )graphVtx )-> coord;
- if( corr[ coord ] != beta ) {
- corr[ coord ] = beta; //added
- change = true;
- }
- else {
- corr[ coord ] = beta;
- }
- } /* if( ( ( Edge* )graphEdge ) -> weight == ... else */
-
- } /* for( i = 0; i < s; i ++ ) */
-
- cvClearGraph( hlpGraph );
- cvClearGraph( graph );
-
- cvRestoreMemStoragePos( storage, &storagePos );
-
- return change;
-
-} /* oneStep */
-
-// function initCorr fills correspondence array with initial values
-// corr - pointer to correspondence array for this line
-// width - width of image line in pixels
-// maxPixelDifference - maximum value of difference between the same
-// point painted on two images
-void initCorr( int* corr, int width, int maxPixelDifference )
-{
- int i;
- int pixelDifferenceRange = maxPixelDifference * 2 + 1;
-
- for( i = 0; i < width; i ++ )
- {
- corr[ i ] = i % pixelDifferenceRange - maxPixelDifference;
- }
-} /* initCorr */
-
-// function oneLineCorr fully computes one line of images
-// leftLine - pointer to the left image line
-// rightLine - pointer to the right image line
-// corr - pointer to the correspondence array for one
-// line
-// mem - pointer to memory allocated by allocTempMem
-// function
-// vertices - pointer to memory allocated by allocTempMem
-// function
-// width - width of image line in pixels
-// maxPixelDifference - maximum value of pixel differences in pixels
-// storage - pointer to CvMemStorage struct which
-// contains memory storage
-void oneLineCorr( unsigned char* leftLine,
- unsigned char* rightLine,
- int* corr,
- int* mem,
- int* vertices,
- int width,
- int maxPixelDifference,
- CvMemStorage* storage )
-{
- int result = 1;
- int count = 0;
- int i, j;
-
- initCorr( corr, width, maxPixelDifference );
- while( result )
- {
- result = 0;
-
- for( i = - maxPixelDifference; i < maxPixelDifference; i ++ )
- for( j = i + 1; j <= maxPixelDifference; j ++ )
- {
- result += (int)oneStep( leftLine,
- rightLine,
- i,
- j,
- corr,
- width,
- mem,
- vertices,
- storage );
- } /* for( j = i + 1; j < width; j ++ ) */
-
- count ++;
- if( count > /*0*//*1*/2 ) {
- break;
- }
-
- } /* while( result ) */
-
-} /* oneLineCorr */
-
-// function allLinesCorr computes all lines on the images
-// leftImage - pointer to the left image
-// leftLineStep - size of line on the left image in bytes
-// rightImage - pointer to the right image
-// rightLineStep - size of line on the right image in bytes
-// width - width of line in pixels
-// height - height of image in pixels
-// corr - pointer to correspondence array for all lines
-// maxPixelDifference - maximum value of difference between the same
-// point painted on two images
-// storage - pointer to CvMemStorage which contains memory
-// storage
-void allLinesCorr( unsigned char* leftImage,
- int leftLineStep,
- unsigned char* rightImage,
- int rightLineStep,
- int width,
- int height,
- int* corr,
- int maxPixelDifference,
- CvMemStorage* storage )
-{
- int i;
- unsigned char* leftLine = leftImage;
- unsigned char* rightLine = rightImage;
- int* mem;
- int* vertices;
-
- allocTempMem( &mem,
- &vertices,
- width );
-
- for( i = 0; i < height; i ++ )
- {
- oneLineCorr( leftLine,
- rightLine,
- corr + i * width,
- mem,
- vertices,
- width,
- maxPixelDifference,
- storage );
- leftLine += leftLineStep;
- rightLine += rightLineStep;
- } /* for( i = 0; i < height; i ++ ) */
-
- freeTempMem( &mem,
- &vertices );
-
-} /* allLinesCorr */
-
-// This function produces morphing of two images into one image, which includes morphed
-// image or depth map
-// _leftImage - pointer to left image
-// _leftLineStep - size of line on left image in bytes
-// _rightImage - pointer to right image
-// _rightLineStep - size of line on right image in bytes
-// _resultImage - pointer to result morphed image
-// _resultLineStep - size of line on result image in bytes
-// _corrArray - pointer to array with correspondences
-// _numCorrArray - pointer to array with numbers correspondeces on each line
-// width - width of images
-// height - height of images
-// alpha - position of virtual camera ( 0 corresponds to left image, 1 - to right one )
-// imageNeed - defines your wishes. if you want to see normal morphed image you have to set
-// this parameter to morphNormalImage ( this is default value ), else if you want
-// to see depth map you have to set this parameter to morphDepthMap and set the
-// next parameter ( maxPixelDifference ) to real value
-// maxPixelDifference - maximum value of pixel difference on two images
-void CCvGraphCutMorpher::Morph( unsigned char* _leftImage,
- int _leftLineStep,
- unsigned char* _rightImage,
- int _rightLineStep,
- unsigned char* _resultImage,
- int _resultLineStep,
- int* _corrArray,
- int width,
- int height,
- float alpha,
- morphImageType imageNeed,
- int maxDifference
- )
-{
- unsigned char* leftArray = _leftImage;
- unsigned char* middleArray = _resultImage;
- unsigned char* rightArray = _rightImage;
- int leftLineSize = _leftLineStep;
- int middleLineSize = _resultLineStep;
- int rightLineSize = _rightLineStep;
-
- int lineNumber;
- unsigned char* leftTemp;
- unsigned char* middleTemp;
- unsigned char* rightTemp;
- int leftPixel;
- int prevLeftPixel;
- int middlePixel;
- int prevMiddlePixel;
- int rightPixel;
- int prevRightPixel;
- int leftPixel3;
- int middlePixel3;
- int rightPixel3;
- int i;
- int j;
- int tempIndex;
- int* result;
- int number;
- float alpha1 = 1.0f - alpha;
-
- for( lineNumber = 0; lineNumber < height; lineNumber ++ )
- {
- leftTemp = leftArray + leftLineSize * lineNumber;
- middleTemp = middleArray + middleLineSize * lineNumber;
- rightTemp = rightArray + rightLineSize * lineNumber;
- memset( ( void* )middleTemp, 0, middleLineSize );
-
- result = _corrArray + width * lineNumber;
- number = width;
-
- prevLeftPixel = 0;
- prevRightPixel = prevLeftPixel + result[ 0 ];
- if( prevRightPixel >= width ) {
- prevRightPixel = width - 1;
- }
- else if ( prevRightPixel < 0 ) {
- prevRightPixel = 0;
- }
- prevMiddlePixel =
- (int)( prevLeftPixel * alpha1 + prevRightPixel * alpha );
- for( i = 0; i < number - 1; i ++ )
- {
- leftPixel = i;
- rightPixel = i + result[ i ];
- if( rightPixel >= width ) {
- rightPixel = width - 1;
- }
- else if( rightPixel < 0 ) {
- rightPixel = 0;
- }
- middlePixel =
- (int)( leftPixel * alpha1 + rightPixel * alpha );
- leftPixel3 = leftPixel * 3;
- middlePixel3 = middlePixel * 3;
- rightPixel3 = rightPixel * 3;
-
- if( imageNeed == morphDepthMap ) {
- int t = leftPixel - rightPixel + maxDifference;
- t = t < 0 ? -t : t;
- t = t * 255 / maxDifference / 2;
- middleTemp[ middlePixel3 ] = ( unsigned char )t;
- middleTemp[ middlePixel3 + 1 ] = ( unsigned char )t;
- middleTemp[ middlePixel3 + 2 ] = ( unsigned char )t;
- } // if( imageNeed == morphDepthMap )
- else
- {
- middleTemp[ middlePixel3 ] =
- (unsigned char)( leftTemp[ leftPixel3 ] * alpha1
- + rightTemp[ rightPixel3 ] * alpha );
- middleTemp[ middlePixel3 + 1 ] =
- (unsigned char)( leftTemp[ leftPixel3 + 1 ] * alpha1
- + rightTemp[ rightPixel3 + 1 ] * alpha );
- middleTemp[ middlePixel3 + 2 ] =
- (unsigned char)( leftTemp[ leftPixel3 + 2 ] * alpha1
- + rightTemp[ rightPixel3 + 2 ] * alpha );
-
- if( middlePixel - prevMiddlePixel > 1 ) // occlusion
- {
- if( leftPixel - prevLeftPixel > 1 )
- {
- int LenSrc = leftPixel - prevLeftPixel - 2;
- int LenDest = middlePixel - prevMiddlePixel - 1;
- for( j = prevMiddlePixel + 1; j < middlePixel; j ++ )
- {
- tempIndex = prevLeftPixel + 1 + LenSrc *
- ( j - prevMiddlePixel - 1 ) / LenDest;
- middleTemp[ j * 3 ] =
- leftTemp[ tempIndex * 3 ];
- middleTemp[ j * 3 + 1 ] =
- leftTemp[ tempIndex * 3 + 1 ];
- middleTemp[ j * 3 + 2 ] =
- leftTemp[ tempIndex * 3 + 2 ];
- }
- } // if( leftPixel - prevLeftPixel > 1 )
- else
- {
- int LenSrc = rightPixel - prevRightPixel - 2;
- int LenDest = middlePixel - prevMiddlePixel - 1;
- for( j = prevMiddlePixel + 1; j < middlePixel; j ++ )
- {
- tempIndex = prevRightPixel + 1 + LenSrc *
- ( j - prevMiddlePixel - 1 ) / LenDest;
- middleTemp[ j * 3 ] =
- rightTemp[ tempIndex * 3 ];
- middleTemp[ j * 3 + 1 ] =
- rightTemp[ tempIndex * 3 + 1 ];
- middleTemp[ j * 3 + 2 ] =
- rightTemp[ tempIndex * 3 + 2 ];
- }
- } // if( leftPixel - prevLeftPixel > 1 ) else
-
- } // if( middlePixel - prevMiddlePixel > 1 )
-
- } // if( imageNeed == morphDepthMap ) else
-
- if( middlePixel > prevMiddlePixel ) {
- if( leftPixel > prevLeftPixel )
- prevLeftPixel = leftPixel;
- if( rightPixel > prevRightPixel )
- prevRightPixel = rightPixel;
- prevMiddlePixel = middlePixel;
- }
- } // for( i = number - 1; i >= 0; i -- )
-
- } // for( lineNumber = 0; lineNumber < LeftImage -> m_Raster -> GetHeight() )
-
-} // Morph
-
-bool CCvGraphCutMorpher::OnCalculateStereo()
-{
- CvSize imageSizeLeft = GetImageSize( m_left_img ),
- imageSizeRight = GetImageSize( m_right_img );
-
- if( ( imageSizeLeft.width != imageSizeRight.width )
- || ( imageSizeLeft.height != imageSizeRight.height ) )
- {
- return false;
- }
-
- if( m_corr ) {
- free( m_corr );
- m_corr = NULL;
- }
- m_corr = ( int* ) malloc( m_left_img -> width
- * m_left_img -> height
- * sizeof( int ) );
-
- if( !m_storage ) {
- m_storage = cvCreateMemStorage( 0 );
- m_isStorageAllocated = true;
- }
- // Find correspondence for full image and store it to corr array
- allLinesCorr( ( unsigned char* )m_left_img -> imageData,
- m_left_img -> widthStep,
- ( unsigned char* )m_right_img -> imageData,
- m_right_img -> widthStep,
- m_left_img -> width,
- m_left_img -> height,
- m_corr,
- m_maxPixelDifference,
- m_storage );
-
- m_isStereoReady = true;
-
- return true;
-}
-
-bool CCvGraphCutMorpher::OnCalculateVirtualImage()
-{
- // Output image to ResultImage window
- Morph( ( unsigned char* )m_left_img -> imageData,
- m_left_img ->widthStep,
- ( unsigned char* )m_right_img -> imageData,
- m_right_img -> widthStep,
- ( unsigned char* )m_virtual_img -> imageData,
- m_virtual_img -> widthStep,
- m_corr,
- m_left_img -> width,
- m_left_img -> height,
- m_pan );
-
- m_isVirtualImageReady = true;
-
- return true;
-}
-
-bool CCvGraphCutMorpher::OnCalculateDisparity()
-{
- Morph( ( unsigned char* )m_left_img -> imageData,
- m_left_img ->widthStep,
- ( unsigned char* )m_right_img -> imageData,
- m_right_img -> widthStep,
- ( unsigned char* )m_disparity_img -> imageData,
- m_disparity_img -> widthStep,
- m_corr,
- m_left_img -> width,
- m_left_img -> height,
- m_pan,
- morphDepthMap,
- m_maxPixelDifference );
-
- return true;
-}
-
-bool CCvGraphCutMorpher::OnCalculateDisparityImage()
-{
- Morph( ( unsigned char* )m_left_img -> imageData,
- m_left_img ->widthStep,
- ( unsigned char* )m_right_img -> imageData,
- m_right_img -> widthStep,
- ( unsigned char* )m_disparity_img -> imageData,
- m_disparity_img -> widthStep,
- m_corr,
- m_left_img -> width,
- m_left_img -> height,
- m_pan,
- morphDepthMap,
- m_maxPixelDifference );
-
- return true;
-}
-
-CCvGraphCutMorpher::CCvGraphCutMorpher()
-{
- m_maxPixelDifference = MAX_DIFFERENCE;
- m_corr = 0;
- m_isStereoReady = false;
- m_isVirtualImageReady = false;
- m_isDisparityReady = false;
- m_storage = NULL;
- m_isStorageAllocated = false;
-}
-
-#endif
-
-/* End of file */