int main() { // Minimize the following function of 3 binary variables: // E(x, y, z) = x - 2*y + 3*(1-z) - 4*x*y + 5*|y-z| Energy<float,float,float>::Var varx, vary, varz; Energy<float,float,float> *e = new Energy<float,float,float>(3,2); varx = e -> add_variable(); vary = e -> add_variable(); varz = e -> add_variable(); e -> add_term1(varx, 0, 1); // add term x e -> add_term1(vary, 0, -2); // add term -2*y e -> add_term1(varz, 3, 0); // add term 3*(1-z) e -> add_term2(varx, vary, 0, 0, 0, -4); // add term -4*x*y e -> add_term2(vary, varz, 0, 5, 5, 0); // add term 5*|y-z| Energy<float,float,float>::TotalValue Emin = e -> minimize(); printf("Minimum = %f\n", Emin); printf("Optimal solution:\n"); printf("x = %d\n", e->get_var(varx)); printf("y = %d\n", e->get_var(vary)); printf("z = %d\n", e->get_var(varz)); delete e; return 0; }
//----------------------------------------------------------------------------------- void GCoptimization::solveSwap(SiteID size,SiteID *activeSites,LabelID alpha_label, LabelID beta_label) { SiteID i,site; if ( !readyToOptimise() ) handleError("Set up data and smoothness terms first. "); if ( size == 0 ) 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(); set_up_swap_energy(size,alpha_label,beta_label,e,variables,activeSites); Energy::TotalValue Emin = e -> minimize(); for ( i = 0; i < size; i++ ) { site = activeSites[i]; if ( e->get_var(variables[i]) == 0 ) m_labeling[site] = alpha_label; else m_labeling[site] = beta_label; m_lookupSiteVar[site] = -1; } delete [] variables; delete e; }
void Swap::perform_alpha_beta_swap(LabelType alpha_label, LabelType beta_label) { PixelType i,size = 0; Energy *e = new Energy(); for ( i = 0; i < m_nPixels; i++ ) { if ( m_labeling[i] == alpha_label || m_labeling[i] == beta_label) { m_pixels[size] = i; m_lookupPixVar[i] = size; size++; } } if ( size == 0 ) return; Energy::Var *variables = (Energy::Var *) new Energy::Var[size]; if (!variables) { fprintf(stderr, "Not enough memory!\n"); exit(1); } 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,m_pixels); else add_t_links_FnPix_swap(e,variables,size,alpha_label,beta_label,m_pixels); if ( m_grid_graph ) { if ( m_smoothType != FUNCTION ) { if (m_varWeights) set_up_swap_energy_G_ARRAY_VW(size,alpha_label,beta_label,m_pixels,e,variables); else set_up_swap_energy_G_ARRAY(size,alpha_label,beta_label,m_pixels,e,variables); } else set_up_swap_energy_G_FnPix(size,alpha_label,beta_label,m_pixels,e,variables); } else { if ( m_smoothType != FUNCTION ) set_up_swap_energy_NG_ARRAY(size,alpha_label,beta_label,m_pixels,e,variables); else set_up_swap_energy_NG_FnPix(size,alpha_label,beta_label,m_pixels,e,variables); } e -> minimize(); for ( i = 0; i < size; i++ ) if ( e->get_var(variables[i]) == 0 ) m_labeling[m_pixels[i]] = alpha_label; else m_labeling[m_pixels[i]] = beta_label; delete [] variables; delete e; }
void Match::BVZ_Expand(Coord a) { Coord p, d, q, dq; Energy::Var var, qvar; int E_old, E00, E0a, Ea0; int k; /* node_vars stores variables corresponding to nodes */ Energy *e = new Energy(BVZ_error_function); /* initializing */ for (p.y=0; p.y<im_size.y; p.y++) for (p.x=0; p.x<im_size.x; p.x++) { d = Coord(IMREF(x_left, p), IMREF(y_left, p)); if (a == d) { IMREF(node_vars, p) = VAR_ACTIVE; e -> add_constant(BVZ_data_penalty(p, d)); } else { IMREF(node_vars, p) = var = e -> add_variable(); e -> ADD_TERM1(var, BVZ_data_penalty(p, d), BVZ_data_penalty(p, a)); } } for (p.y=0; p.y<im_size.y; p.y++) for (p.x=0; p.x<im_size.x; p.x++) { d = Coord(IMREF(x_left, p), IMREF(y_left, p)); var = (Energy::Var) IMREF(node_vars, p); /* smoothness term */ for (k=0; k<NEIGHBOR_NUM; k++) { q = p + NEIGHBORS[k]; if ( ! ( q>=Coord(0,0) && q<im_size ) ) continue; qvar = (Energy::Var) IMREF(node_vars, q); dq = Coord(IMREF(x_left, q), IMREF(y_left, q)); if (var != VAR_ACTIVE && qvar != VAR_ACTIVE) E00 = BVZ_smoothness_penalty(p, q, d, dq); if (var != VAR_ACTIVE) E0a = BVZ_smoothness_penalty(p, q, d, a); if (qvar != VAR_ACTIVE) Ea0 = BVZ_smoothness_penalty(p, q, a, dq); if (var != VAR_ACTIVE) { if (qvar != VAR_ACTIVE) e -> ADD_TERM2(var, qvar, E00, E0a, Ea0, 0); else e -> ADD_TERM1(var, E0a, 0); } else { if (qvar != VAR_ACTIVE) e -> ADD_TERM1(qvar, Ea0, 0); else {} } } } E_old = E; E = e -> minimize(); if (E < E_old) { for (p.y=0; p.y<im_size.y; p.y++) for (p.x=0; p.x<im_size.x; p.x++) { var = (Energy::Var) IMREF(node_vars, p); if (var!=VAR_ACTIVE && e->get_var(var)==VALUE1) { IMREF(x_left, p) = a.x; IMREF(y_left, p) = a.y; } } } delete e; }
void Expansion::perform_alpha_expansion(LabelType alpha_label) { PixelType i,size = 0; Energy *e = new Energy(); for ( i = 0; i < m_nPixels; i++ ) { if ( m_labeling[i] != alpha_label ) { m_lookupPixVar[size] = i; size++; } } if ( size > 0 ) { Energy::Var *variables = (Energy::Var *) new Energy::Var[size]; if ( !variables) { printf("\nOut of memory, exiting"); exit(1); } 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 add_t_links_FnPix(e,variables,size,alpha_label); if ( m_grid_graph ) { if ( m_smoothType != FUNCTION ) { if (m_varWeights) 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 set_up_expansion_energy_G_FnPix(size,alpha_label,e,variables); } else { if ( m_smoothType != FUNCTION ) set_up_expansion_energy_NG_ARRAY(size,alpha_label,e,variables); else if ( m_smoothType == FUNCTION) set_up_expansion_energy_NG_FnPix(size,alpha_label,e,variables); } e -> minimize(); for ( i = 0,size = 0; i < m_nPixels; i++ ) { if ( m_labeling[i] != alpha_label ) { if ( e->get_var(variables[size]) == 0 ) m_labeling[i] = alpha_label; size++; } } delete [] variables; } delete e; }
void expandOnLabel(int label,int width,int height,int num_pixels, vector<int> &Seeds,int numSeeds, vector<int> &labeling, vector<Value> &horizWeights,vector<Value> &vertWeights,Value lambda, vector<Value> &diag1Weights,vector<Value> &diag2Weights,int PATCH_SIZE, vector<int> &changeMask, vector<int> &changeMaskNew,image<uchar> *I, int TYPE,float variance) { int seedX,seedY,startX,startY,endX,endY,numVars,blockWidth; getBounds(width,height,Seeds,&seedX,&seedY,&startX,&startY,&endX,&endY,label,PATCH_SIZE); int somethingChanged = 0; for ( int y = startY; y <= endY; y++ ) for ( int x = startX; x <= endX; x++ ) if ( changeMask[x+y*width] == 1 ) { somethingChanged = 1; break; } if ( somethingChanged == 0) return; blockWidth = endX-startX+1; numVars = (endY-startY+1)*blockWidth; vector<Var> variables(numVars); Energy<int,int,int> *e = new Energy<int,int,int>(numVars,numVars*3); for ( int i = 0; i < numVars; i++ ) variables[i] = e->add_variable(); Value LARGE_WEIGHT = lambda*NUM_COLORS*8; // First fix the border to old labels, except the edges of the image for ( int y = startY; y <= endY; y++ ){ if ( startX != 0 ) e->add_term1(variables[(y-startY)*blockWidth],0,LARGE_WEIGHT); else if ( y == startY || y == endY) e->add_term1(variables[(y-startY)*blockWidth],0,LARGE_WEIGHT); if( endX != width -1 ) e->add_term1(variables[(endX-startX)+(y-startY)*blockWidth],0,LARGE_WEIGHT); else if ( y == startY || y == endY) e->add_term1(variables[(endX-startX)+(y-startY)*blockWidth],0,LARGE_WEIGHT); } for ( int x = startX+1; x < endX; x++){ if ( startY != 0 ) e->add_term1(variables[(x-startX)],0,LARGE_WEIGHT); if ( endY != height - 1) e->add_term1(variables[(x-startX)+(endY-startY)*blockWidth],0,LARGE_WEIGHT); } // add links to center of the patch for color constant superpixels if ( TYPE == 1 ) { int color = imRef(I,seedX,seedY); for ( int y = startY+1; y < endY; y++ ) for ( int x = startX+1; x < endX; x++){ Value E00=0,E01=0,E10=LARGE_WEIGHT,E11=0; if (seedX != x && seedY != y) e->add_term2(variables[(x-startX)+(y-startY)*blockWidth], variables[(seedX-startX)+(seedY-startY)*blockWidth],E00,E01,E10,E11); int diff = abs(imRef(I,x,y)-color); int maxD = (int) variance*MULTIPLIER_VAR; if ( diff > maxD ) diff = maxD; int oldLabel = labeling[x+y*width]; int oldY = Seeds[oldLabel]/width; int oldX = Seeds[oldLabel]-oldY*width; int oldColor = imRef(I,oldX,oldY); int oldDiff = abs(imRef(I,x,y)-oldColor); if ( oldDiff > maxD ) oldDiff = maxD; if ( oldDiff > diff) e->add_term1(variables[(x-startX)+(y-startY)*blockWidth],oldDiff-diff,0); else e->add_term1(variables[(x-startX)+(y-startY)*blockWidth],0,diff-oldDiff); } } // First set up horizontal links for ( int y = startY; y <= endY; y++ ) for ( int x = startX+1; x <=endX; x++){ int oldLabelPix = labeling[x+y*width]; int oldLabelNeighbPix = labeling[x-1+y*width]; Value E00,E01,E10,E11=0; if ( oldLabelPix != oldLabelNeighbPix ) E00 = horizWeights[x-1+y*width]; else E00 = 0; if ( oldLabelNeighbPix != label ) E01 = horizWeights[x-1+y*width]; else E01 = 0; if ( label != oldLabelPix ) E10 = horizWeights[x-1+y*width]; else E10 = 0; e->add_term2(variables[(x-startX)-1+(y-startY)*blockWidth],variables[(x-startX)+(y-startY)*blockWidth],E00,E01,E10,E11); } // Next set up vertical links for ( int y = startY+1; y <= endY; y++ ) for ( int x = startX; x <=endX; x++){ int oldLabelPix = labeling[x+y*width]; int oldLabelNeighbPix = labeling[x+(y-1)*width]; Value E00,E01,E10,E11=0; if ( oldLabelPix != oldLabelNeighbPix ) E00 = vertWeights[x+(y-1)*width]; else E00 = 0; if ( oldLabelNeighbPix != label ) E01 = vertWeights[x+(y-1)*width]; else E01 = 0; if ( label != oldLabelPix ) E10 = vertWeights[x+(y-1)*width]; else E10 = 0; e->add_term2(variables[(x-startX)+(y-startY-1)*blockWidth],variables[(x-startX)+(y-startY)*blockWidth],E00,E01,E10,E11); } // Next set up diagonal links float SQRT_2= 1/sqrt(2.0); for ( int y = startY+1; y <= endY; y++ ) for ( int x = startX+1; x <=endX; x++){ int oldLabelPix = labeling[x+y*width]; int oldLabelNeighbPix = labeling[x-1+(y-1)*width]; Value E00,E01,E10,E11=0; if ( oldLabelPix != oldLabelNeighbPix ) E00 = SQRT_2*diag1Weights[x-1+(y-1)*width]; else E00 = 0; if ( oldLabelNeighbPix != label ) E01 = SQRT_2*diag1Weights[x-1+(y-1)*width]; else E01 = 0; if ( label != oldLabelPix ) E10 = SQRT_2*diag1Weights[x-1+(y-1)*width]; else E10 = 0; e->add_term2(variables[(x-startX)-1+(y-startY-1)*blockWidth],variables[(x-startX)+(y-startY)*blockWidth],E00,E01,E10,E11); } // More diagonal links for ( int y = startY+1; y <= endY; y++ ) for ( int x = startX; x <=endX-1; x++){ int oldLabelPix = labeling[x+y*width]; int oldLabelNeighbPix = labeling[(x+1)+(y-1)*width]; Value E00,E01,E10,E11=0; if ( oldLabelPix != oldLabelNeighbPix ) E00 = SQRT_2*diag2Weights[(x+1)+(y-1)*width]; else E00 = 0; if ( oldLabelNeighbPix != label ) E01 = SQRT_2*diag2Weights[(x+1)+(y-1)*width]; else E01 = 0; if ( label != oldLabelPix ) E10 = SQRT_2*diag2Weights[(x+1)+(y-1)*width]; else E10 = 0; e->add_term2(variables[(x-startX+1)+(y-startY-1)*blockWidth],variables[(x-startX)+(y-startY)*blockWidth],E00,E01,E10,E11); } e->minimize(); for ( int y = startY; y <= endY; y++ ) for ( int x = startX; x <= endX; x++){ if ( e->get_var(variables[(x-startX)+(y-startY)*blockWidth]) != 0 ) { if ( labeling[x+y*width] != label ){ labeling[x+y*width] = label; changeMaskNew[x+y*width] = 1; changeMask[x+y*width] = 1; } } } delete e; }
/* computes the minimum a-expansion configuration */ void Match::KZ1_Expand(Coord a) { Coord p, q, d, dq; Energy::Var var, qvar; int E_old, delta, E00, E0a, Ea0, Eaa; int k; Energy *e = new Energy(KZ1_error_function); /* initializing */ for (p.y=0; p.y<im_size.y; p.y++) for (p.x=0; p.x<im_size.x; p.x++) { d = Coord(IMREF(x_left, p), IMREF(y_left, p)); if (a == d) IMREF(node_vars_left, p) = VAR_ACTIVE; else { IMREF(node_vars_left, p) = var = e -> add_variable(); if (d.x == OCCLUDED) e -> ADD_TERM1(var, KZ1_OCCLUSION_PENALTY, 0); } d = Coord(IMREF(x_right, p), IMREF(y_right, p)); if (a == -d) IMREF(node_vars_right, p) = VAR_ACTIVE; else { IMREF(node_vars_right, p) = var = e -> add_variable(); if (d.x == OCCLUDED) e -> ADD_TERM1(var, KZ1_OCCLUSION_PENALTY, 0); } } for (p.y=0; p.y<im_size.y; p.y++) for (p.x=0; p.x<im_size.x; p.x++) { /* data and visibility terms */ d = Coord(IMREF(x_left, p), IMREF(y_left, p)); var = (Energy::Var) IMREF(node_vars_left, p); if (d != a && d.x != OCCLUDED) { q = p + d; if (q>=Coord(0,0) && q<im_size) { qvar = (Energy::Var) IMREF(node_vars_right, q); dq = Coord(IMREF(x_right, q), IMREF(y_right, q)); if (d == -dq) { delta = (is_blocked(a, d)) ? INFINITY : 0; e -> ADD_TERM2(var, qvar, KZ1_data_penalty(p, q), delta, delta, 0); } else if (is_blocked(a, d)) { e -> ADD_TERM2(var, qvar, 0, INFINITY, 0, 0); } } } q = p + a; if (q>=Coord(0,0) && q<im_size) { qvar = (Energy::Var) IMREF(node_vars_right, q); dq = Coord(IMREF(x_right, q), IMREF(y_right, q)); E0a = (is_blocked(d, a)) ? INFINITY : 0; Ea0 = (is_blocked(-dq, a)) ? INFINITY : 0; Eaa = KZ1_data_penalty(p, q); if (var != VAR_ACTIVE) { if (qvar != VAR_ACTIVE) e -> ADD_TERM2(var, qvar, 0, E0a, Ea0, Eaa); else e -> ADD_TERM1(var, E0a, Eaa); } else { if (qvar != VAR_ACTIVE) e -> ADD_TERM1(qvar, Ea0, Eaa); else e -> add_constant(Eaa); } } /* left smoothness term */ for (k=0; k<NEIGHBOR_NUM; k++) { q = p + NEIGHBORS[k]; if ( ! ( q>=Coord(0,0) && q<im_size ) ) continue; qvar = (Energy::Var) IMREF(node_vars_left, q); dq = Coord(IMREF(x_left, q), IMREF(y_left, q)); if (var != VAR_ACTIVE && qvar != VAR_ACTIVE) E00 = KZ1_smoothness_penalty_left(p, q, d, dq); if (var != VAR_ACTIVE) E0a = KZ1_smoothness_penalty_left(p, q, d, a); if (qvar != VAR_ACTIVE) Ea0 = KZ1_smoothness_penalty_left(p, q, a, dq); if (var != VAR_ACTIVE) { if (qvar != VAR_ACTIVE) e -> ADD_TERM2(var, qvar, E00, E0a, Ea0, 0); else e -> ADD_TERM1(var, E0a, 0); } else { if (qvar != VAR_ACTIVE) e -> ADD_TERM1(qvar, Ea0, 0); else {} } } /* right smoothness term */ d = Coord(IMREF(x_right, p), IMREF(y_right, p)); var = (Energy::Var) IMREF(node_vars_right, p); for (k=0; k<NEIGHBOR_NUM; k++) { q = p + NEIGHBORS[k]; if ( ! ( q>=Coord(0,0) && q<im_size ) ) continue; qvar = (Energy::Var) IMREF(node_vars_right, q); dq = Coord(IMREF(x_right, q), IMREF(y_right, q)); if (var != VAR_ACTIVE && qvar != VAR_ACTIVE) E00 = KZ1_smoothness_penalty_right(p, q, d, dq); if (var != VAR_ACTIVE) E0a = KZ1_smoothness_penalty_right(p, q, d, -a); if (qvar != VAR_ACTIVE) Ea0 = KZ1_smoothness_penalty_right(p, q, -a, dq); if (var != VAR_ACTIVE) { if (qvar != VAR_ACTIVE) e -> ADD_TERM2(var, qvar, E00, E0a, Ea0, 0); else e -> ADD_TERM1(var, E0a, 0); } else { if (qvar != VAR_ACTIVE) e -> ADD_TERM1(qvar, Ea0, 0); else {} } } /* visibility term */ if (d.x != OCCLUDED && is_blocked(a, -d)) { q = p + d; if (q>=Coord(0,0) && q<im_size) { if (d.x != -IMREF(x_left, q) || d.y != -IMREF(y_left, q)) e -> ADD_TERM2(var, (Energy::Var) IMREF(node_vars_left, q), 0, INFINITY, 0, 0); } } } E_old = E; E = e -> minimize(); if (E < E_old) { for (p.y=0; p.y<im_size.y; p.y++) for (p.x=0; p.x<im_size.x; p.x++) { var = (Energy::Var) IMREF(node_vars_left, p); if (var != VAR_ACTIVE && e->get_var(var)==VALUE1) { IMREF(x_left, p) = a.x; IMREF(y_left, p) = a.y; } var = (Energy::Var) IMREF(node_vars_right, p); if (var != VAR_ACTIVE && e->get_var(var)==VALUE1) { IMREF(x_right, p) = -a.x; IMREF(y_right, p) = -a.y; } } } delete e; }