www.pudn.com > maxflow_fast2.rar > GCoptimization.cpp
#include "Energy.h" #include "Graph.h" #include "GCoptimization.h" #include#include #include #define MAX_INTT 1000000000 /**************************************************************************************/ void GCoptimization::initialize_memory() { m_lookupPixVar = (PixelType *) new PixelType[m_num_pixels]; m_labelTable = (LabelType *) new LabelType[m_num_labels]; terminateOnError( !m_lookupPixVar || !m_labelTable,"Not enough memory"); for ( int i = 0; i < m_num_labels; i++ ) m_labelTable[i] = i; for ( i = 0; i < m_num_pixels; i++ ) m_lookupPixVar[i] = -1; } /**************************************************************************************/ void GCoptimization::commonGridInitialization(PixelType width, PixelType height, int nLabels) { terminateOnError( (width < 0) || (height <0) || (nLabels <0 ),"Illegal negative parameters"); m_width = width; m_height = height; m_num_pixels = width*height; m_num_labels = nLabels; m_grid_graph = 1; srand(time(NULL)); } /**************************************************************************************/ void GCoptimization::commonNonGridInitialization(PixelType nupixels, int num_labels) { terminateOnError( (nupixels <0) || (num_labels <0 ),"Illegal negative parameters"); m_num_labels = num_labels; m_num_pixels = nupixels; m_grid_graph = 0; m_neighbors = (LinkedBlockList *) new LinkedBlockList[nupixels]; terminateOnError(!m_neighbors,"Not enough memory"); } /**************************************************************************************/ void GCoptimization::commonInitialization(int dataSetup, int smoothSetup) { int i; m_random_label_order = 1; m_dataInput = dataSetup; m_smoothInput = smoothSetup; if (m_dataInput == SET_INDIVIDUALLY ) { m_datacost = (EnergyTermType *) new EnergyTermType[m_num_labels*m_num_pixels]; terminateOnError(!m_datacost,"Not enough memory"); for ( i = 0; i < m_num_labels*m_num_pixels; i++ ) m_datacost[i] = (EnergyTermType) 0; m_dataType = ARRAY; } else m_dataType = NONE; if ( m_smoothInput == SET_INDIVIDUALLY ) { m_smoothcost = (EnergyTermType *) new EnergyTermType[m_num_labels*m_num_labels]; terminateOnError(!m_smoothcost,"Not enough memory"); for ( i = 0; i < m_num_labels*m_num_labels; i++ ) m_smoothcost[i] = (EnergyTermType) 0; m_smoothType = ARRAY; m_varying_weights = 0; } else m_smoothType = NONE; initialize_memory(); srand(time(NULL)); } /**************************************************************************************/ /* Use this constructor only for grid graphs */ GCoptimization::GCoptimization(PixelType width,PixelType height,int nLabels,int dataSetup, int smoothSetup ) { commonGridInitialization(width,height,nLabels); m_labeling = (LabelType *) new LabelType[m_num_pixels]; terminateOnError(!m_labeling,"out of memory"); for ( int i = 0; i < m_num_pixels; i++ ) m_labeling[i] = (LabelType) 0; m_deleteLabeling = 1; commonInitialization(dataSetup,smoothSetup); } /**************************************************************************************/ /* Use this constructor only for grid graphs */ GCoptimization::GCoptimization(LabelType *m_answer,PixelType width,PixelType height,int nLabels, int dataSetup, int smoothSetup) { commonGridInitialization(width,height,nLabels); m_labeling = m_answer; for ( int i = 0; i < m_num_pixels; i++ ) terminateOnError(m_labeling[i] < 0 || m_labeling[i] >= nLabels,"Initial labels are out of valid range"); m_deleteLabeling = 0; commonInitialization(dataSetup,smoothSetup); } /**************************************************************************************/ /* Use this constructor for general graphs */ GCoptimization::GCoptimization(PixelType nupixels,int nLabels,int dataSetup, int smoothSetup ) { commonNonGridInitialization(nupixels, nLabels); m_labeling = (LabelType *) new LabelType[m_num_pixels]; terminateOnError(!m_labeling,"out of memory"); for ( int i = 0; i < nupixels; i++ ) m_labeling[i] = (LabelType) 0; m_deleteLabeling = 1; commonInitialization(dataSetup,smoothSetup); } /**************************************************************************************/ /* Use this constructor for general graphs */ GCoptimization::GCoptimization(LabelType *m_answer, PixelType nupixels,int nLabels,int dataSetup, int smoothSetup) { commonNonGridInitialization(nupixels, nLabels); m_labeling = m_answer; for ( int i = 0; i < m_num_pixels; i++ ) terminateOnError(m_labeling[i] < 0 || m_labeling[i] >= nLabels,"Initial labels are out of valid range"); m_deleteLabeling = 0; commonInitialization(dataSetup,smoothSetup); } /**************************************************************************************/ void GCoptimization::setData(EnergyTermType* dataArray) { terminateOnError(m_dataType != NONE, "ERROR: you already set the data, or said you'll use member function setDataCost() to set data"); m_datacost = dataArray; m_dataType = ARRAY; } /**************************************************************************************/ void GCoptimization::setData(dataFnPix dataFn) { terminateOnError(m_dataType != NONE, "ERROR: you already set the data, or said you'll use member function setDataCost() to set data"); m_dataFnPix = dataFn; m_dataType = FUNCTION_PIX; } /**************************************************************************************/ void GCoptimization::setData(dataFnCoord dataFn) { terminateOnError(m_dataType != NONE, "ERROR: you already set the data, or said you'll use member function setDataCost() to set data"); terminateOnError( !m_grid_graph,"Cannot use data function based on coordinates for non-grid graph"); m_dataFnCoord = dataFn; m_dataType = FUNCTION_COORD; } /**************************************************************************************/ void GCoptimization::setSmoothness(EnergyTermType* V) { terminateOnError(m_smoothType != NONE, "ERROR: you already set smoothness, or said you'll use member function setSmoothCost() to set Smoothness Costs"); m_smoothType = ARRAY; m_smoothcost = V; m_varying_weights = 0; } /**************************************************************************************/ void GCoptimization::setSmoothness(EnergyTermType* V,EnergyTermType* hCue, EnergyTermType* vCue) { terminateOnError(m_smoothType != NONE, "ERROR: you already set smoothness, or said you'll use member function setSmoothCost() to set Smoothness Costs"); terminateOnError(!m_grid_graph, "ERROR: for a grid graph, you can't use vertical and horizontal cues. Use setNeighbors() member function to encode spatially varying cues"); m_varying_weights = 1; m_smoothType = ARRAY; m_vertWeights = vCue; m_horizWeights = hCue; m_smoothcost = V; } /**************************************************************************************/ void GCoptimization::setSmoothness(smoothFnCoord horz_cost, smoothFnCoord vert_cost) { terminateOnError(m_smoothType != NONE, "ERROR: you already set smoothness, or said you'll use member function setSmoothCost() to set Smoothness Costs"); terminateOnError( !m_grid_graph,"Cannot use smoothness function based on coordinates for non-grid graph"); m_smoothType = FUNCTION_COORD; m_horz_cost = horz_cost; m_vert_cost = vert_cost; } /**************************************************************************************/ void GCoptimization::setSmoothness(smoothFnPix cost) { terminateOnError(m_smoothType != NONE, "ERROR: you already set smoothness, or said you'll use member function setSmoothCost() to set Smoothness Costs"); m_smoothType = FUNCTION_PIX; m_smoothFnPix = cost; } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::giveDataEnergy() { if ( m_dataType == ARRAY) return(giveDataEnergyArray()); else if ( m_dataType == FUNCTION_PIX ) return(giveDataEnergyFnPix()); else if (m_dataType == FUNCTION_COORD ) return(giveDataEnergyFnCoord()); else terminateOnError(1,"Did not initialize the data costs yet"); return(0); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::giveDataEnergyArray() { EnergyType eng = (EnergyType) 0; for ( int i = 0; i < m_num_pixels; i++ ) if (m_labeling[i] != m_num_labels+1) eng = eng + m_datacost(i,m_labeling[i]); return(eng); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::giveDataEnergyFnPix() { EnergyType eng = (EnergyType) 0; for ( int i = 0; i < m_num_pixels; i++ ) eng = eng + m_dataFnPix(i,m_labeling[i]); return(eng); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::giveDataEnergyFnCoord() { EnergyType eng = (EnergyType) 0; for ( int y = 0; y < m_height; y++ ) for ( int x = 0; x < m_width; x++ ) eng = eng + m_dataFnCoord(x,y,m_labeling[x+y*m_width]); return(eng); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::giveSmoothEnergy() { if ( m_grid_graph ) { if ( m_smoothType == ARRAY ) { if (m_varying_weights) return(giveSmoothEnergy_G_ARRAY_VW()); else return(giveSmoothEnergy_G_ARRAY()); } else if ( m_smoothType == FUNCTION_PIX ) return(giveSmoothEnergy_G_FnPix()); else if ( m_smoothType == FUNCTION_COORD ) return(giveSmoothEnergy_G_FnCoord()); else terminateOnError(1,"Did not initialize smoothness costs yet, can't compute smooth energy"); } else { if ( m_smoothType == ARRAY ) return(giveSmoothEnergy_NG_ARRAY()); else if ( m_smoothType == FUNCTION_PIX ) return(giveSmoothEnergy_NG_FnPix()); else terminateOnError(1,"Did not initialize smoothness costs yet, can't compute smooth energy"); } return(0); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_NG_FnPix() { EnergyType eng = (EnergyType) 0; int i; Neighbor *temp; for ( i = 0; i < m_num_pixels; i++ ) if ( !m_neighbors[i].isEmpty() ) { m_neighbors[i].setCursorFront(); while ( m_neighbors[i].hasNext() ) { temp = (Neighbor *) m_neighbors[i].next(); if ( i < temp->to_node ) eng = eng + m_smoothFnPix(i,temp->to_node, m_labeling[i],m_labeling[temp->to_node]); } } return(eng); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_NG_ARRAY() { EnergyType eng = (EnergyType) 0; int i; Neighbor *temp; for ( i = 0; i < m_num_pixels; i++ ) if ( !m_neighbors[i].isEmpty() ) { m_neighbors[i].setCursorFront(); while ( m_neighbors[i].hasNext() ) { temp = (Neighbor *) m_neighbors[i].next(); if ( i < temp->to_node ) eng = eng + m_smoothcost(m_labeling[i],m_labeling[temp->to_node])*(temp->weight); } } return(eng); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_G_ARRAY_VW() { EnergyType eng = (EnergyType) 0; int x,y,pix; printf("\nIn right place"); for ( y = 0; y < m_height; y++ ) for ( x = 1; x < m_width; x++ ) if ((m_labeling[x+y*m_width-1] != m_num_labels +1) &&(m_labeling[x+y*m_width] != m_num_labels +1) ) { pix = x+y*m_width; eng = eng + m_smoothcost(m_labeling[pix],m_labeling[pix-1])*m_horizWeights[pix-1]; } for ( y = 1; y < m_height; y++ ) for ( x = 0; x < m_width; x++ )if ((m_labeling[x+y*m_width-m_width] != m_num_labels +1) &&(m_labeling[x+y*m_width] != m_num_labels +1) ) { pix = x+y*m_width; eng = eng + m_smoothcost(m_labeling[pix],m_labeling[pix-m_width])*m_vertWeights[pix-m_width]; } return(eng); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_G_ARRAY() { EnergyType eng = (EnergyType) 0; int x,y,pix; for ( y = 0; y < m_height; y++ ) for ( x = 1; x < m_width; x++ ) { pix = x+y*m_width; eng = eng + m_smoothcost(m_labeling[pix],m_labeling[pix-1]); } for ( y = 1; y < m_height; y++ ) for ( x = 0; x < m_width; x++ ) { pix = x+y*m_width; eng = eng + m_smoothcost(m_labeling[pix],m_labeling[pix-m_width]); } return(eng); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_G_FnPix() { EnergyType eng = (EnergyType) 0; int x,y,pix; for ( y = 0; y < m_height; y++ ) for ( x = 1; x < m_width; x++ ) { pix = x+y*m_width; eng = eng + m_smoothFnPix(pix,pix-1,m_labeling[pix],m_labeling[pix-1]); } for ( y = 1; y < m_height; y++ ) for ( x = 0; x < m_width; x++ ) { pix = x+y*m_width; eng = eng + m_smoothFnPix(pix,pix-m_width,m_labeling[pix],m_labeling[pix-m_width]); } return(eng); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_G_FnCoord() { EnergyType eng = (EnergyType) 0; int x,y,pix; for ( y = 0; y < m_height; y++ ) for ( x = 1; x < m_width; x++ ) { pix = x+y*m_width; eng = eng + m_horz_cost(x-1,y,m_labeling[pix-1],m_labeling[pix]); } for ( y = 1; y < m_height; y++ ) for ( x = 0; x < m_width; x++ ) { pix = x+y*m_width; eng = eng + m_vert_cost(x,y-1,m_labeling[pix-m_width],m_labeling[pix]); } return(eng); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::compute_energy() { return(giveDataEnergy()+giveSmoothEnergy()); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::expansion(int max_num_iterations) { return(start_expansion(max_num_iterations)); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::expansion() { return(start_expansion(MAX_INTT)); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::start_expansion(int max_num_iterations ) { int curr_cycle = 1; EnergyType new_energy,old_energy; new_energy = compute_energy(); old_energy = new_energy+1; while ( old_energy > new_energy && curr_cycle <= max_num_iterations) { old_energy = new_energy; new_energy = oneExpansionIteration(); curr_cycle++; } return(new_energy); } /****************************************************************************/ void GCoptimization::scramble_label_table() { LabelType r1,r2,temp; int num_times,cnt; num_times = m_num_labels*2; for ( cnt = 0; cnt < num_times; cnt++ ) { r1 = rand()%m_num_labels; r2 = rand()%m_num_labels; temp = m_labelTable[r1]; m_labelTable[r1] = m_labelTable[r2]; m_labelTable[r2] = temp; } } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::alpha_expansion(LabelType label) { terminateOnError( label < 0 || label >= m_num_labels,"Illegal Label to Expand On"); perform_alpha_expansion(label); return(compute_energy()); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::alpha_expansion(LabelType alpha_label, PixelType *pixels, int num ) { PixelType i,size = 0; Energy *e = new Energy(); for ( i = 0; i < num; i++ ) { if ( m_labeling[pixels[i]] != alpha_label ) { m_lookupPixVar[pixels[i]] = i; } } if ( size > 0 ) { Energy::Var *variables = (Energy::Var *) new Energy::Var[size]; for ( i = 0; i < size; i++ ) variables[i] = e ->add_variable(); if ( m_dataType == ARRAY ) add_t_links_ARRAY(e,variables,size,alpha_label); else if ( m_dataType == FUNCTION_PIX ) add_t_links_FnPix(e,variables,size,alpha_label); else add_t_links_FnCoord(e,variables,size,alpha_label); if ( m_grid_graph ) { if ( m_smoothType == ARRAY ) { if (m_varying_weights) set_up_expansion_energy_G_ARRAY_VW_pix(size,alpha_label,e,variables,pixels,num); else set_up_expansion_energy_G_ARRAY_pix(size,alpha_label,e,variables,pixels,num); } else if ( m_smoothType == FUNCTION_PIX ) { printf("NOT SUPPORTED YET,exiting!"); exit(0); //if ( m_smoothType == FUNCTION_PIX ) set_up_expansion_energy_G_FnPix_pix(size,alpha_label,e,variables); } else { printf("NOT SUPPORTED YET,exiting!"); exit(0); //set_up_expansion_energy_G_FnCoord_pix(size,alpha_label,e,variables); } } else { printf("NOT SUPPORTED YET,exiting!"); exit(0); /*if ( m_smoothType == ARRAY ) set_up_expansion_energy_NG_ARRAY_pix(size,alpha_label,e,variables); else if ( m_smoothType == FUNCTION_PIX ) set_up_expansion_energy_NG_FnPix_pix(size,alpha_label,e,variables);*/ } e -> minimize(); for ( i = 0; i < num; i++ ) { if ( m_labeling[pixels[i]] != alpha_label ) { if ( e->get_var(variables[i]) == 0 ) m_labeling[pixels[i]] = alpha_label; } m_lookupPixVar[pixels[i]] = -1; } delete [] variables; } delete e; return(compute_energy()); } /**************************************************************************************/ void GCoptimization::add_t_links_ARRAY(Energy *e,Energy::Var *variables,int size,LabelType alpha_label) { for ( int i = 0; i < size; i++ ) e -> add_term1(variables[i], m_datacost(m_lookupPixVar[i],alpha_label), m_datacost(m_lookupPixVar[i],m_labeling[m_lookupPixVar[i]])); } /**************************************************************************************/ void GCoptimization::add_t_links_FnPix(Energy *e,Energy::Var *variables,int size,LabelType alpha_label) { for ( int i = 0; i < size; i++ ) e -> add_term1(variables[i], m_dataFnPix(m_lookupPixVar[i],alpha_label), m_dataFnPix(m_lookupPixVar[i],m_labeling[m_lookupPixVar[i]])); } /**************************************************************************************/ void GCoptimization::add_t_links_FnCoord(Energy *e,Energy::Var *variables,int size,LabelType alpha_label) { int x,y; for ( int i = 0; i < size; i++ ) { y = m_lookupPixVar[i]/m_width; x = m_lookupPixVar[i] - y*m_width; e -> add_term1(variables[i], m_dataFnCoord(x,y,alpha_label), m_dataFnCoord(x,y,m_labeling[m_lookupPixVar[i]])); } } /**************************************************************************************/ void GCoptimization::perform_alpha_expansion(LabelType alpha_label,int *pixels, int num_pixels) { PixelType i,size = 0,nextPix; Energy *e = new Energy(); if ( num_pixels > m_num_pixels ) { printf("Error! number of pixels on which to do alpha-expansion has to be less than the total number of pixels. Exiting"); exit(0); } for ( i = 0; i < num_pixels; i++ ) { nextPix = pixels[i]; assert(nextPix >= 0 && nextPix < m_num_pixels); if ( m_labeling[nextPix] != alpha_label ) { m_lookupPixVar[size] = nextPix; size++; } } if ( size > 0 ) { Energy::Var *variables = (Energy::Var *) new Energy::Var[size]; for ( i = 0; i < size; i++ ) variables[i] = e ->add_variable(); if ( m_dataType == ARRAY ) add_t_links_ARRAY(e,variables,size,alpha_label); else if ( m_dataType == FUNCTION_PIX ) add_t_links_FnPix(e,variables,size,alpha_label); else add_t_links_FnCoord(e,variables,size,alpha_label); if ( m_grid_graph ) { if ( m_smoothType == ARRAY ) { if (m_varying_weights) set_up_expansion_energy_G_ARRAY_VW(size,alpha_label,e,variables); else set_up_expansion_energy_G_ARRAY(size,alpha_label,e,variables); } else if ( m_smoothType == FUNCTION_PIX ) set_up_expansion_energy_G_FnPix(size,alpha_label,e,variables); else set_up_expansion_energy_G_FnCoord(size,alpha_label,e,variables); } else { if ( m_smoothType == ARRAY ) set_up_expansion_energy_NG_ARRAY(size,alpha_label,e,variables); else if ( m_smoothType == FUNCTION_PIX ) set_up_expansion_energy_NG_FnPix(size,alpha_label,e,variables); } e -> minimize(); for ( i = 0,size = 0; i < num_pixels; i++ ) { nextPix = pixels[i]; if ( m_labeling[nextPix] != alpha_label ) { if ( e->get_var(variables[size]) == 0 ) m_labeling[nextPix] = alpha_label; size++; } } delete [] variables; } delete e; } /**************************************************************************************/ void GCoptimization::perform_alpha_expansion(LabelType alpha_label) { PixelType i,size = 0; Energy *e = new Energy(); for ( i = 0; i < m_num_pixels; i++ ) { if ( m_labeling[i] != alpha_label ) { m_lookupPixVar[size] = i; size++; } } if ( size > 0 ) { Energy::Var *variables = (Energy::Var *) new Energy::Var[size]; for ( i = 0; i < size; i++ ) variables[i] = e ->add_variable(); if ( m_dataType == ARRAY ) add_t_links_ARRAY(e,variables,size,alpha_label); else if ( m_dataType == FUNCTION_PIX ) add_t_links_FnPix(e,variables,size,alpha_label); else add_t_links_FnCoord(e,variables,size,alpha_label); if ( m_grid_graph ) { if ( m_smoothType == ARRAY ) { if (m_varying_weights) set_up_expansion_energy_G_ARRAY_VW(size,alpha_label,e,variables); else set_up_expansion_energy_G_ARRAY(size,alpha_label,e,variables); } else if ( m_smoothType == FUNCTION_PIX ) set_up_expansion_energy_G_FnPix(size,alpha_label,e,variables); else set_up_expansion_energy_G_FnCoord(size,alpha_label,e,variables); } else { if ( m_smoothType == ARRAY ) set_up_expansion_energy_NG_ARRAY(size,alpha_label,e,variables); else if ( m_smoothType == FUNCTION_PIX ) set_up_expansion_energy_NG_FnPix(size,alpha_label,e,variables); } e -> minimize(); for ( i = 0,size = 0; i < m_num_pixels; i++ ) { if ( m_labeling[i] != alpha_label ) { if ( e->get_var(variables[size]) == 0 ) m_labeling[i] = alpha_label; size++; } } delete [] variables; } delete e; } /**********************************************************************************************/ /* Performs alpha-expansion for non regular grid graph for case when energy terms are NOT */ /* specified by a function */ void GCoptimization::set_up_expansion_energy_NG_ARRAY(int size, LabelType alpha_label,Energy *e,Energy::Var *variables ) { EnergyTermType weight; Neighbor *tmp; int i,nPix,pix;; for ( i = size - 1; i >= 0; i-- ) { pix = m_lookupPixVar[i]; m_lookupPixVar[pix] = i; if ( !m_neighbors[pix].isEmpty() ) { m_neighbors[pix].setCursorFront(); while ( m_neighbors[pix].hasNext() ) { tmp = (Neighbor *) (m_neighbors[pix].next()); nPix = tmp->to_node; weight = tmp->weight; if ( m_labeling[nPix] != alpha_label ) { if ( pix < nPix ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label)*weight, m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(m_labeling[pix],alpha_label)*weight, m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight); } else e ->add_term1(variables[i],m_smoothcost(alpha_label,alpha_label)*weight, m_smoothcost(m_labeling[pix],alpha_label)*weight); } } } } /**********************************************************************************************/ /* Performs alpha-expansion for non regular grid graph for case when energy terms are */ /* specified by a function */ void GCoptimization::set_up_expansion_energy_NG_FnPix(int size, LabelType alpha_label,Energy *e,Energy::Var *variables ) { Neighbor *tmp; int i,nPix,pix; for ( i = size - 1; i >= 0; i-- ) { pix = m_lookupPixVar[i]; m_lookupPixVar[pix] = i; if ( !m_neighbors[pix].isEmpty() ) { m_neighbors[pix].setCursorFront(); while ( m_neighbors[pix].hasNext() ) { tmp = (Neighbor *) (m_neighbors[pix].next()); nPix = tmp->to_node; if ( m_labeling[nPix] != alpha_label ) { if ( pix < nPix ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothFnPix(pix,nPix,alpha_label,alpha_label), m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label), m_smoothFnPix(pix,nPix,m_labeling[pix],m_labeling[nPix])); } else e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label)); } } } } /**********************************************************************************************/ /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */ /* specified by a function */ void GCoptimization::set_up_expansion_energy_G_ARRAY_VW(int size, LabelType alpha_label,Energy *e, Energy::Var *variables ) { int i,nPix,pix,x,y; EnergyTermType weight; for ( i = size - 1; i >= 0; i-- ) { pix = m_lookupPixVar[i]; y = pix/m_width; x = pix - y*m_width; m_lookupPixVar[pix] = i; if ( x < m_width - 1 ) { nPix = pix + 1; weight = m_horizWeights[pix]; if ( m_labeling[nPix] != alpha_label ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label)*weight, m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(m_labeling[pix],alpha_label)*weight, m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(m_labeling[pix],alpha_label)*weight); } if ( y < m_height - 1 ) { nPix = pix + m_width; weight = m_vertWeights[pix]; if ( m_labeling[nPix] != alpha_label ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label)*weight , m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(m_labeling[pix],alpha_label)*weight , m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight ); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(m_labeling[pix],alpha_label)*weight); } if ( x > 0 ) { nPix = pix - 1; if ( m_labeling[nPix] == alpha_label ) e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*m_horizWeights[nPix], m_smoothcost(m_labeling[pix],alpha_label)*m_horizWeights[nPix]); } if ( y > 0 ) { nPix = pix - m_width; if ( m_labeling[nPix] == alpha_label ) e ->add_term1(variables[i],m_smoothcost(alpha_label,alpha_label)*m_vertWeights[nPix], m_smoothcost(m_labeling[pix],alpha_label)*m_vertWeights[nPix]); } } } /**********************************************************************************************/ /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */ /* specified by a function */ void GCoptimization::set_up_expansion_energy_G_ARRAY(int size, LabelType alpha_label,Energy *e, Energy::Var *variables ) { int i,nPix,pix,x,y; for ( i = size - 1; i >= 0; i-- ) { pix = m_lookupPixVar[i]; y = pix/m_width; x = pix - y*m_width; m_lookupPixVar[pix] = i; if ( x < m_width - 1 ) { nPix = pix + 1; if ( m_labeling[nPix] != alpha_label ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label), m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(m_labeling[pix],alpha_label), m_smoothcost(m_labeling[pix],m_labeling[nPix])); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(m_labeling[pix],alpha_label)); } if ( y < m_height - 1 ) { nPix = pix + m_width; if ( m_labeling[nPix] != alpha_label ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label) , m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(m_labeling[pix],alpha_label) , m_smoothcost(m_labeling[pix],m_labeling[nPix]) ); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(m_labeling[pix],alpha_label)); } if ( x > 0 ) { nPix = pix - 1; if ( m_labeling[nPix] == alpha_label ) e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(m_labeling[pix],alpha_label) ); } if ( y > 0 ) { nPix = pix - m_width; if ( m_labeling[nPix] == alpha_label ) e ->add_term1(variables[i],m_smoothcost(alpha_label,alpha_label), m_smoothcost(m_labeling[pix],alpha_label)); } } } /**********************************************************************************************/ /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */ /* specified by a function */ void GCoptimization::set_up_expansion_energy_G_ARRAY_VW_pix(int size, LabelType alpha_label,Energy *e, Energy::Var *variables, PixelType *pixels, int num ) { int i,nPix,pix,x,y; EnergyTermType weight; for ( i = 0; i < num; i++ ) { pix = pixels[i]; if ( m_labeling[pix]!= alpha_label ) { y = pix/m_width; x = pix - y*m_width; if ( x < m_width - 1 ) { nPix = pix + 1; weight = m_horizWeights[pix]; if ( m_labeling[nPix] != alpha_label && m_lookupPixVar[nPix] != -1 ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label)*weight, m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(m_labeling[pix],alpha_label)*weight, m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight); } if ( y < m_height - 1 ) { nPix = pix + m_width; weight = m_vertWeights[pix]; if ( m_labeling[nPix] != alpha_label && m_lookupPixVar[nPix] != -1 ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label)*weight , m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(m_labeling[pix],alpha_label)*weight , m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight ); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight); } if ( x > 0 ) { nPix = pix - 1; if ( m_labeling[nPix] == alpha_label || m_lookupPixVar[nPix] == -1) e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*m_horizWeights[nPix], m_smoothcost(m_labeling[pix],m_labeling[nPix])*m_horizWeights[nPix]); } if ( y > 0 ) { nPix = pix - m_width; if ( m_labeling[nPix] == alpha_label || m_lookupPixVar[nPix] == -1) e ->add_term1(variables[i],m_smoothcost(alpha_label,alpha_label)*m_vertWeights[nPix], m_smoothcost(m_labeling[pix],m_labeling[nPix])*m_vertWeights[nPix]); } } } } /**********************************************************************************************/ /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */ /* specified by a function */ void GCoptimization::set_up_expansion_energy_G_ARRAY_pix(int size, LabelType alpha_label,Energy *e, Energy::Var *variables, PixelType *pixels, int num) { int i,nPix,pix,x,y; for ( i = 0; i < num; i++ ) { pix = pixels[i]; y = pix/m_width; x = pix - y*m_width; if ( m_labeling[pix]!= alpha_label ) { if ( x < m_width - 1 ) { nPix = pix + 1; if ( m_labeling[nPix] != alpha_label && m_lookupPixVar[pix] != -1) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label), m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(m_labeling[pix],alpha_label), m_smoothcost(m_labeling[pix],m_labeling[nPix])); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(m_labeling[pix],m_labeling[nPix])); } if ( y < m_height - 1 ) { nPix = pix + m_width; if ( m_labeling[nPix] != alpha_label && m_lookupPixVar[pix] != -1) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label) , m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(m_labeling[pix],alpha_label) , m_smoothcost(m_labeling[pix],m_labeling[nPix]) ); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(m_labeling[pix],m_labeling[nPix])); } if ( x > 0 ) { nPix = pix - 1; if ( m_labeling[nPix] == alpha_label || m_lookupPixVar[nPix] == -1) e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(m_labeling[pix],m_labeling[nPix]) ); } if ( y > 0 ) { nPix = pix - m_width; if ( m_labeling[nPix] == alpha_label || m_lookupPixVar[nPix] == -1) e ->add_term1(variables[i],m_smoothcost(alpha_label,alpha_label), m_smoothcost(m_labeling[pix],m_labeling[nPix])); } } } } /**********************************************************************************************/ /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */ /* specified by a function */ void GCoptimization::set_up_expansion_energy_G_FnPix(int size, LabelType alpha_label,Energy *e, Energy::Var *variables ) { int i,nPix,pix,x,y; for ( i = size - 1; i >= 0; i-- ) { pix = m_lookupPixVar[i]; y = pix/m_width; x = pix - y*m_width; m_lookupPixVar[pix] = i; if ( x < m_width - 1 ) { nPix = pix + 1; if ( m_labeling[nPix] != alpha_label ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothFnPix(pix,nPix,alpha_label,alpha_label), m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label), m_smoothFnPix(pix,nPix,m_labeling[pix],m_labeling[nPix])); else e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label)); } if ( y < m_height - 1 ) { nPix = pix + m_width; if ( m_labeling[nPix] != alpha_label ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothFnPix(pix,nPix,alpha_label,alpha_label) , m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label) , m_smoothFnPix(pix,nPix,m_labeling[pix],m_labeling[nPix]) ); else e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label)); } if ( x > 0 ) { nPix = pix - 1; if ( m_labeling[nPix] == alpha_label ) e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label) ); } if ( y > 0 ) { nPix = pix - m_width; if ( m_labeling[nPix] == alpha_label ) e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,alpha_label), m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label)); } } } /**********************************************************************************************/ /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */ /* specified by a function */ void GCoptimization::set_up_expansion_energy_G_FnCoord(int size, LabelType alpha_label,Energy *e, Energy::Var *variables ) { int i,nPix,pix,x,y; for ( i = size - 1; i >= 0; i-- ) { pix = m_lookupPixVar[i]; y = pix/m_width; x = pix - y*m_width; m_lookupPixVar[pix] = i; if ( x < m_width - 1 ) { nPix = pix + 1; if ( m_labeling[nPix] != alpha_label ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_horz_cost(x,y,alpha_label,alpha_label), m_horz_cost(x,y,alpha_label,m_labeling[nPix]), m_horz_cost(x,y,m_labeling[pix],alpha_label), m_horz_cost(x,y,m_labeling[pix],m_labeling[nPix])); else e ->add_term1(variables[i],m_horz_cost(x,y,alpha_label,alpha_label), m_horz_cost(x,y,m_labeling[pix],alpha_label)); } if ( y < m_height - 1 ) { nPix = pix + m_width; if ( m_labeling[nPix] != alpha_label ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_vert_cost(x,y,alpha_label,alpha_label) , m_vert_cost(x,y,alpha_label,m_labeling[nPix]), m_vert_cost(x,y,m_labeling[pix],alpha_label) , m_vert_cost(x,y,m_labeling[pix],m_labeling[nPix]) ); else e ->add_term1(variables[i],m_vert_cost(x,y,alpha_label,alpha_label), m_vert_cost(x,y,m_labeling[pix],alpha_label)); } if ( x > 0 ) { nPix = pix - 1; if ( m_labeling[nPix] == alpha_label ) e ->add_term1(variables[i],m_horz_cost(x-1,y,alpha_label,m_labeling[nPix]), m_horz_cost(x-1,y,m_labeling[pix],alpha_label) ); } if ( y > 0 ) { nPix = pix - m_width; if ( m_labeling[nPix] == alpha_label ) e ->add_term1(variables[i],m_vert_cost(x,y-1,alpha_label,alpha_label), m_vert_cost(x,y-1,m_labeling[pix],alpha_label)); } } } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::oneExpansionIteration() { int next; terminateOnError( m_dataType == NONE,"You have to set up the data cost before running optimization"); terminateOnError( m_smoothType == NONE,"You have to set up the smoothness cost before running optimization"); if (m_random_label_order) scramble_label_table(); for (next = 0; next < m_num_labels; next++ ) perform_alpha_expansion(m_labelTable[next]); return(compute_energy()); } /**************************************************************************************/ void GCoptimization::setNeighbors(PixelType pixel1, PixelType pixel2, EnergyTermType weight) { assert(pixel1 < m_num_pixels && pixel1 >= 0 && pixel2 < m_num_pixels && pixel2 >= 0); assert(m_grid_graph == 0); Neighbor *temp1 = (Neighbor *) new Neighbor; Neighbor *temp2 = (Neighbor *) new Neighbor; temp1->weight = weight; temp1->to_node = pixel2; temp2->weight = weight; temp2->to_node = pixel1; m_neighbors[pixel1].addFront(temp1); m_neighbors[pixel2].addFront(temp2); } /**************************************************************************************/ void GCoptimization::setNeighbors(PixelType pixel1, PixelType pixel2) { assert(pixel1 < m_num_pixels && pixel1 >= 0 && pixel2 < m_num_pixels && pixel2 >= 0); assert(m_grid_graph == 0); Neighbor *temp1 = (Neighbor *) new Neighbor; Neighbor *temp2 = (Neighbor *) new Neighbor; temp1->weight = (EnergyTermType) 1; temp1->to_node = pixel2; temp2->weight = (EnergyTermType) 1; temp2->to_node = pixel1; m_neighbors[pixel1].addFront(temp1); m_neighbors[pixel2].addFront(temp2); } /**************************************************************************************/ GCoptimization::~GCoptimization() { if ( m_deleteLabeling ) delete [] m_labeling; if ( m_dataInput == SET_INDIVIDUALLY ) delete [] m_datacost; if ( m_smoothInput == SET_INDIVIDUALLY ) delete [] m_smoothcost; if ( ! m_grid_graph ) delete [] m_neighbors; delete [] m_labelTable; delete [] m_lookupPixVar; } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::swap(int max_num_iterations) { return(start_swap(max_num_iterations)); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::swap() { return(start_swap(MAX_INTT)); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::start_swap(int max_num_iterations ) { int curr_cycle = 1; EnergyType new_energy,old_energy; new_energy = compute_energy(); old_energy = new_energy+1; while ( old_energy > new_energy && curr_cycle <= max_num_iterations) { old_energy = new_energy; new_energy = oneSwapIteration(); curr_cycle++; } return(new_energy); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::oneSwapIteration() { int next,next1; if (m_random_label_order) scramble_label_table(); for (next = 0; next < m_num_labels; next++ ) for (next1 = m_num_labels - 1; next1 >= 0; next1-- ) if ( m_labelTable[next] < m_labelTable[next1] ) perform_alpha_beta_swap(m_labelTable[next],m_labelTable[next1]); return(compute_energy()); } /**************************************************************************************/ GCoptimization::EnergyType GCoptimization::alpha_beta_swap(LabelType alpha_label, LabelType beta_label) { terminateOnError( alpha_label < 0 || alpha_label >= m_num_labels || beta_label < 0 || beta_label >= m_num_labels, "Illegal Label to Expand On"); perform_alpha_beta_swap(alpha_label,beta_label); return(compute_energy()); } /**************************************************************************************/ void GCoptimization::alpha_beta_swap(LabelType alpha_label, LabelType beta_label, PixelType *alphaPixels,int alpha_size, PixelType *betaPixels, int beta_size) { terminateOnError( alpha_label < 0 || alpha_label >= m_num_labels || beta_label < 0 || beta_label >= m_num_labels, "Illegal Label to Expand On"); perform_alpha_beta_swap(alpha_label,beta_label,alphaPixels,alpha_size,betaPixels,beta_size); } /**************************************************************************************/ void GCoptimization::add_t_links_ARRAY_swap(Energy *e,Energy::Var *variables,int size, LabelType alpha_label, LabelType beta_label, PixelType *pixels) { for ( int i = 0; i < size; i++ ) e -> add_term1(variables[i], m_datacost(pixels[i],alpha_label), m_datacost(pixels[i],beta_label)); } /**************************************************************************************/ void GCoptimization::add_t_links_FnPix_swap(Energy *e,Energy::Var *variables,int size, LabelType alpha_label, LabelType beta_label, PixelType *pixels) { for ( int i = 0; i < size; i++ ) e -> add_term1(variables[i], m_dataFnPix(pixels[i],alpha_label), m_dataFnPix(pixels[i],beta_label)); } /**************************************************************************************/ void GCoptimization::add_t_links_FnCoord_swap(Energy *e,Energy::Var *variables,int size, LabelType alpha_label, LabelType beta_label, PixelType *pixels) { int x,y; for ( int i = 0; i < size; i++ ) { y = pixels[i]/m_width; x = pixels[i] - y*m_width; e -> add_term1(variables[i], m_dataFnCoord(x,y,alpha_label),m_dataFnCoord(x,y,beta_label)); } } /**************************************************************************************/ void GCoptimization::perform_alpha_beta_swap(LabelType alpha_label, LabelType beta_label, int *alphaPixels,int alpha_size, int *betaPixels, int beta_size) { PixelType i,size = 0,pix; PixelType *pixels = new PixelType[alpha_size + beta_size]; for ( i = 0; i < alpha_size; i++ ) { pix = alphaPixels[i]; assert(pix >= 0 && pix < m_num_pixels ); assert(m_labeling[pix] == alpha_label); pixels[size] = pix; m_lookupPixVar[pix] = size; size++; } for ( i = 0; i < beta_size; i++ ) { pix = betaPixels[i]; assert(pix >= 0 && pix < m_num_pixels ); assert(m_labeling[pix] == beta_label); pixels[size] = pix; m_lookupPixVar[pix] = size; size++; } if ( size == 0 ){ delete [] pixels; return; } Energy *e = new Energy(); Energy::Var *variables = (Energy::Var *) new Energy::Var[size]; for ( i = 0; i < size; i++ ) variables[i] = e ->add_variable(); if ( m_dataType == ARRAY ) add_t_links_ARRAY_swap(e,variables,size,alpha_label,beta_label,pixels); else if ( m_dataType == FUNCTION_PIX ) add_t_links_FnPix_swap(e,variables,size,alpha_label,beta_label,pixels); else add_t_links_FnCoord_swap(e,variables,size,alpha_label,beta_label,pixels); if ( m_grid_graph ) { if ( m_smoothType == ARRAY ) { if (m_varying_weights) set_up_swap_energy_G_ARRAY_VW(size,alpha_label,beta_label,pixels,e,variables); else set_up_swap_energy_G_ARRAY(size,alpha_label,beta_label,pixels,e,variables); } else if ( m_smoothType == FUNCTION_PIX ) set_up_swap_energy_G_FnPix(size,alpha_label,beta_label,pixels,e,variables); else set_up_swap_energy_G_FnCoord(size,alpha_label,beta_label,pixels,e,variables); } else { if ( m_smoothType == ARRAY ) set_up_swap_energy_NG_ARRAY(size,alpha_label,beta_label,pixels,e,variables); else if ( m_smoothType == FUNCTION_PIX ) set_up_swap_energy_NG_FnPix(size,alpha_label,beta_label,pixels,e,variables); } e -> minimize(); for ( i = 0; i < size; i++ ) if ( e->get_var(variables[i]) == 0 ) m_labeling[pixels[i]] = alpha_label; else m_labeling[pixels[i]] = beta_label; delete [] variables; delete [] pixels; delete e; } /**************************************************************************************/ void GCoptimization::perform_alpha_beta_swap(LabelType alpha_label, LabelType beta_label) { PixelType i,size = 0; Energy *e = new Energy(); PixelType *pixels = new PixelType[m_num_pixels]; for ( i = 0; i < m_num_pixels; i++ ) { if ( m_labeling[i] == alpha_label || m_labeling[i] == beta_label) { pixels[size] = i; m_lookupPixVar[i] = size; size++; } } if ( size == 0 ) { delete e; delete [] pixels; return; } Energy::Var *variables = (Energy::Var *) new Energy::Var[size]; for ( i = 0; i < size; i++ ) variables[i] = e ->add_variable(); if ( m_dataType == ARRAY ) add_t_links_ARRAY_swap(e,variables,size,alpha_label,beta_label,pixels); else if ( m_dataType == FUNCTION_PIX ) add_t_links_FnPix_swap(e,variables,size,alpha_label,beta_label,pixels); else add_t_links_FnCoord_swap(e,variables,size,alpha_label,beta_label,pixels); if ( m_grid_graph ) { if ( m_smoothType == ARRAY ) { if (m_varying_weights) set_up_swap_energy_G_ARRAY_VW(size,alpha_label,beta_label,pixels,e,variables); else set_up_swap_energy_G_ARRAY(size,alpha_label,beta_label,pixels,e,variables); } else if ( m_smoothType == FUNCTION_PIX ) set_up_swap_energy_G_FnPix(size,alpha_label,beta_label,pixels,e,variables); else set_up_swap_energy_G_FnCoord(size,alpha_label,beta_label,pixels,e,variables); } else { if ( m_smoothType == ARRAY ) set_up_swap_energy_NG_ARRAY(size,alpha_label,beta_label,pixels,e,variables); else if ( m_smoothType == FUNCTION_PIX ) set_up_swap_energy_NG_FnPix(size,alpha_label,beta_label,pixels,e,variables); } e -> minimize(); for ( i = 0; i < size; i++ ) if ( e->get_var(variables[i]) == 0 ) m_labeling[pixels[i]] = alpha_label; else m_labeling[pixels[i]] = beta_label; delete [] variables; delete [] pixels; delete e; } /**************************************************************************************/ void GCoptimization::set_up_swap_energy_NG_ARRAY(int size,LabelType alpha_label,LabelType beta_label, PixelType *pixels,Energy* e, Energy::Var *variables) { PixelType nPix,pix,i; EnergyTermType weight; Neighbor *tmp; for ( i = 0; i < size; i++ ) { pix = pixels[i]; if ( !m_neighbors[pix].isEmpty() ) { m_neighbors[pix].setCursorFront(); while ( m_neighbors[pix].hasNext() ) { tmp = (Neighbor *) (m_neighbors[pix].next()); nPix = tmp->to_node; weight = tmp->weight; if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) { if ( pix < nPix ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label)*weight, m_smoothcost(alpha_label,beta_label)*weight, m_smoothcost(beta_label,alpha_label)*weight, m_smoothcost(beta_label,beta_label)*weight); } else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(beta_label,m_labeling[nPix])*weight); } } } } /**************************************************************************************/ void GCoptimization::set_up_swap_energy_NG_FnPix(int size,LabelType alpha_label,LabelType beta_label, PixelType *pixels,Energy* e, Energy::Var *variables) { PixelType nPix,pix,i; Neighbor *tmp; for ( i = 0; i < size; i++ ) { pix = pixels[i]; if ( !m_neighbors[pix].isEmpty() ) { m_neighbors[pix].setCursorFront(); while ( m_neighbors[pix].hasNext() ) { tmp = (Neighbor *) (m_neighbors[pix].next()); nPix = tmp->to_node; if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) { if ( pix < nPix ) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothFnPix(pix,nPix,alpha_label,alpha_label), m_smoothFnPix(pix,nPix,alpha_label,beta_label), m_smoothFnPix(pix,nPix,beta_label,alpha_label), m_smoothFnPix(pix,nPix,beta_label,beta_label) ); } else e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,beta_label,m_labeling[nPix])); } } } } /**************************************************************************************/ void GCoptimization::set_up_swap_energy_G_FnPix(int size,LabelType alpha_label,LabelType beta_label, PixelType *pixels,Energy* e, Energy::Var *variables) { PixelType nPix,pix,i,x,y; for ( i = 0; i < size; i++ ) { pix = pixels[i]; y = pix/m_width; x = pix - y*m_width; if ( x > 0 ) { nPix = pix - 1; if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothFnPix(pix,nPix,alpha_label,alpha_label), m_smoothFnPix(pix,nPix,alpha_label,beta_label), m_smoothFnPix(pix,nPix,beta_label,alpha_label), m_smoothFnPix(pix,nPix,beta_label,beta_label) ); else e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,beta_label,m_labeling[nPix])); } if ( y > 0 ) { nPix = pix - m_width; if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothFnPix(pix,nPix,alpha_label,alpha_label), m_smoothFnPix(pix,nPix,alpha_label,beta_label), m_smoothFnPix(pix,nPix,beta_label,alpha_label), m_smoothFnPix(pix,nPix,beta_label,beta_label) ); else e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,beta_label,m_labeling[nPix])); } if ( x < m_width - 1 ) { nPix = pix + 1; if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) ) e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,beta_label,m_labeling[nPix])); } if ( y < m_height - 1 ) { nPix = pix + m_width; if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) ) e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]), m_smoothFnPix(pix,nPix,beta_label,m_labeling[nPix])); } } } /**************************************************************************************/ void GCoptimization::set_up_swap_energy_G_FnCoord(int size,LabelType alpha_label,LabelType beta_label,PixelType *pixels, Energy* e, Energy::Var *variables) { PixelType nPix,pix,i,x,y; for ( i = 0; i < size; i++ ) { pix = pixels[i]; y = pix/m_width; x = pix - y*m_width; if ( x > 0 ) { nPix = pix - 1; if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_horz_cost(x-1,y,alpha_label,alpha_label), m_horz_cost(x-1,y,alpha_label,beta_label), m_horz_cost(x-1,y,beta_label,alpha_label), m_horz_cost(x-1,y,beta_label,beta_label) ); else e ->add_term1(variables[i],m_horz_cost(x-1,y,alpha_label,m_labeling[nPix]), m_horz_cost(x-1,y,beta_label,m_labeling[nPix])); } if ( y > 0 ) { nPix = pix - m_width; if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_vert_cost(x,y-1,alpha_label,alpha_label), m_vert_cost(x,y-1,alpha_label,beta_label), m_vert_cost(x,y-1,beta_label,alpha_label), m_vert_cost(x,y-1,beta_label,beta_label) ); else e ->add_term1(variables[i],m_vert_cost(x,y-1,alpha_label,m_labeling[nPix]), m_vert_cost(x,y-1,beta_label,m_labeling[nPix])); } if ( x < m_width - 1 ) { nPix = pix + 1; if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) ) e ->add_term1(variables[i],m_horz_cost(x,y,alpha_label,m_labeling[nPix]), m_horz_cost(x,y,beta_label,m_labeling[nPix])); } if ( y < m_height - 1 ) { nPix = pix + m_width; if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) ) e ->add_term1(variables[i],m_vert_cost(x,y,alpha_label,m_labeling[nPix]), m_vert_cost(x,y,beta_label,m_labeling[nPix])); } } } /**************************************************************************************/ void GCoptimization::set_up_swap_energy_G_ARRAY_VW(int size,LabelType alpha_label,LabelType beta_label, PixelType *pixels,Energy* e, Energy::Var *variables) { PixelType nPix,pix,i,x,y; EnergyTermType weight; for ( i = 0; i < size; i++ ) { pix = pixels[i]; y = pix/m_width; x = pix - y*m_width; if ( x > 0 ) { nPix = pix - 1; weight = m_horizWeights[nPix]; if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label)*weight, m_smoothcost(alpha_label,beta_label)*weight, m_smoothcost(beta_label,alpha_label)*weight, m_smoothcost(beta_label,beta_label)*weight ); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(beta_label,m_labeling[nPix])*weight); } if ( y > 0 ) { nPix = pix - m_width; weight = m_vertWeights[nPix]; if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label)*weight, m_smoothcost(alpha_label,beta_label)*weight, m_smoothcost(beta_label,alpha_label)*weight, m_smoothcost(beta_label,beta_label)*weight ); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight, m_smoothcost(beta_label,m_labeling[nPix])*weight); } if ( x < m_width - 1 ) { nPix = pix + 1; if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) ) e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*m_horizWeights[pix], m_smoothcost(beta_label,m_labeling[nPix])*m_horizWeights[pix]); } if ( y < m_height - 1 ) { nPix = pix + m_width; if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) ) e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*m_vertWeights[pix], m_smoothcost(beta_label,m_labeling[nPix])*m_vertWeights[pix]); } } } /**************************************************************************************/ void GCoptimization::set_up_swap_energy_G_ARRAY(int size,LabelType alpha_label,LabelType beta_label, PixelType *pixels,Energy* e, Energy::Var *variables) { PixelType nPix,pix,i,x,y; for ( i = 0; i < size; i++ ) { pix = pixels[i]; y = pix/m_width; x = pix - y*m_width; if ( x > 0 ) { nPix = pix - 1; if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label), m_smoothcost(alpha_label,beta_label), m_smoothcost(beta_label,alpha_label), m_smoothcost(beta_label,beta_label) ); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(beta_label,m_labeling[nPix])); } if ( y > 0 ) { nPix = pix - m_width; if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]], m_smoothcost(alpha_label,alpha_label), m_smoothcost(alpha_label,beta_label), m_smoothcost(beta_label,alpha_label), m_smoothcost(beta_label,beta_label) ); else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(beta_label,m_labeling[nPix])); } if ( x < m_width - 1 ) { nPix = pix + 1; if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) ) e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(beta_label,m_labeling[nPix])); } if ( y < m_height - 1 ) { nPix = pix + m_width; if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label)) e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]), m_smoothcost(beta_label,m_labeling[nPix])); } } } /**************************************************************************************/ void GCoptimization::setLabelOrder(bool RANDOM_LABEL_ORDER) { m_random_label_order = RANDOM_LABEL_ORDER; } /****************************************************************************/ /* This procedure checks if an error has occured, terminates program if yes */ void GCoptimization::terminateOnError(bool error_condition,const char *message) { if (error_condition) { printf("\n %s \n", message); exit(1); } }