3 #include "GCoptimization.h"
\r
7 #define MAX_INTT 1000000000
\r
10 /**************************************************************************************/
\r
12 void GCoptimization::initialize_memory()
\r
16 m_lookupPixVar = (PixelType *) new PixelType[m_num_pixels];
\r
17 m_labelTable = (LabelType *) new LabelType[m_num_labels];
\r
19 terminateOnError( !m_lookupPixVar || !m_labelTable,"Not enough memory");
\r
21 for ( i = 0; i < m_num_labels; i++ )
\r
22 m_labelTable[i] = i;
\r
24 for ( i = 0; i < m_num_pixels; i++ )
\r
25 m_lookupPixVar[i] = -1;
\r
30 /**************************************************************************************/
\r
32 void GCoptimization::commonGridInitialization(PixelType width, PixelType height, int nLabels)
\r
34 terminateOnError( (width < 0) || (height <0) || (nLabels <0 ),"Illegal negative parameters");
\r
38 m_num_pixels = width*height;
\r
39 m_num_labels = nLabels;
\r
45 /**************************************************************************************/
\r
47 void GCoptimization::commonNonGridInitialization(PixelType nupixels, int num_labels)
\r
49 terminateOnError( (nupixels <0) || (num_labels <0 ),"Illegal negative parameters");
\r
51 m_num_labels = num_labels;
\r
52 m_num_pixels = nupixels;
\r
55 m_neighbors = (LinkedBlockList *) new LinkedBlockList[nupixels];
\r
57 terminateOnError(!m_neighbors,"Not enough memory");
\r
61 /**************************************************************************************/
\r
63 void GCoptimization::commonInitialization(int dataSetup, int smoothSetup)
\r
67 m_random_label_order = 1;
\r
68 m_dataInput = dataSetup;
\r
69 m_smoothInput = smoothSetup;
\r
72 if (m_dataInput == SET_INDIVIDUALLY )
\r
74 m_datacost = (EnergyTermType *) new EnergyTermType[m_num_labels*m_num_pixels];
\r
75 terminateOnError(!m_datacost,"Not enough memory");
\r
76 for ( i = 0; i < m_num_labels*m_num_pixels; i++ )
\r
77 m_datacost[i] = (EnergyTermType) 0;
\r
80 else m_dataType = NONE;
\r
83 if ( m_smoothInput == SET_INDIVIDUALLY )
\r
85 m_smoothcost = (EnergyTermType *) new EnergyTermType[m_num_labels*m_num_labels];
\r
86 terminateOnError(!m_smoothcost,"Not enough memory");
\r
87 for ( i = 0; i < m_num_labels*m_num_labels; i++ )
\r
88 m_smoothcost[i] = (EnergyTermType) 0;
\r
90 m_smoothType = ARRAY;
\r
91 m_varying_weights = 0;
\r
93 else m_smoothType = NONE;
\r
96 initialize_memory();
\r
99 // sign class as valid
\r
100 class_sig = VALID_CLASS_SIGNITURE;
\r
101 truncate_flag = false;
\r
105 /**************************************************************************************/
\r
106 /* Use this constructor only for grid graphs */
\r
107 GCoptimization::GCoptimization(PixelType width,PixelType height,int nLabels,int dataSetup, int smoothSetup )
\r
109 commonGridInitialization(width,height,nLabels);
\r
111 m_labeling = (LabelType *) new LabelType[m_num_pixels];
\r
112 terminateOnError(!m_labeling,"out of memory");
\r
113 for ( int i = 0; i < m_num_pixels; i++ ) m_labeling[i] = (LabelType) 0;
\r
115 m_deleteLabeling = 1;
\r
116 commonInitialization(dataSetup,smoothSetup);
\r
119 /**************************************************************************************/
\r
120 /* Use this constructor only for grid graphs */
\r
121 GCoptimization::GCoptimization(LabelType *m_answer,PixelType width,PixelType height,int nLabels,
\r
122 int dataSetup, int smoothSetup)
\r
125 commonGridInitialization(width,height,nLabels);
\r
127 m_labeling = m_answer;
\r
130 for ( int i = 0; i < m_num_pixels; i++ )
\r
131 terminateOnError(m_labeling[i] < 0 || m_labeling[i] >= nLabels,"Initial labels are out of valid range");
\r
133 m_deleteLabeling = 0;
\r
135 commonInitialization(dataSetup,smoothSetup);
\r
138 /**************************************************************************************/
\r
139 /* Use this constructor for general graphs */
\r
140 GCoptimization::GCoptimization(PixelType nupixels,int nLabels,int dataSetup, int smoothSetup )
\r
143 commonNonGridInitialization(nupixels, nLabels);
\r
145 m_labeling = (LabelType *) new LabelType[m_num_pixels];
\r
146 terminateOnError(!m_labeling,"out of memory");
\r
147 for ( int i = 0; i < nupixels; i++ ) m_labeling[i] = (LabelType) 0;
\r
149 m_deleteLabeling = 1;
\r
151 commonInitialization(dataSetup,smoothSetup);
\r
154 /**************************************************************************************/
\r
155 /* Use this constructor for general graphs */
\r
156 GCoptimization::GCoptimization(LabelType *m_answer, PixelType nupixels,int nLabels,int dataSetup, int smoothSetup)
\r
158 commonNonGridInitialization(nupixels, nLabels);
\r
161 m_labeling = m_answer;
\r
162 for ( int i = 0; i < m_num_pixels; i++ )
\r
163 terminateOnError(m_labeling[i] < 0 || m_labeling[i] >= nLabels,"Initial labels are out of valid range");
\r
165 m_deleteLabeling = 0;
\r
167 commonInitialization(dataSetup,smoothSetup);
\r
170 /**************************************************************************************/
\r
172 void GCoptimization::setData(EnergyTermType* dataArray)
\r
174 terminateOnError(m_dataType != NONE,
\r
175 "ERROR: you already set the data, or said you'll use member function setDataCost() to set data");
\r
178 /* allocate memory dinamiocally */
\r
179 m_datacost = (EnergyTermType *) new EnergyTermType[m_num_pixels*m_num_labels];
\r
180 for ( int i(0); i < m_num_pixels*m_num_labels; i++ )
\r
181 m_datacost[i] = dataArray[i];
\r
182 // m_datacost = dataArray;
\r
184 m_dataType = ARRAY;
\r
187 /**************************************************************************************/
\r
189 void GCoptimization::setData(dataFnPix dataFn)
\r
191 terminateOnError(m_dataType != NONE,
\r
192 "ERROR: you already set the data, or said you'll use member function setDataCost() to set data");
\r
194 m_dataFnPix = dataFn;
\r
195 m_dataType = FUNCTION_PIX;
\r
198 /**************************************************************************************/
\r
200 void GCoptimization::setData(dataFnCoord dataFn)
\r
202 terminateOnError(m_dataType != NONE,
\r
203 "ERROR: you already set the data, or said you'll use member function setDataCost() to set data");
\r
205 terminateOnError( !m_grid_graph,"Cannot use data function based on coordinates for non-grid graph");
\r
207 m_dataFnCoord = dataFn;
\r
208 m_dataType = FUNCTION_COORD;
\r
211 /**************************************************************************************/
\r
213 void GCoptimization::setSmoothness(EnergyTermType* V)
\r
216 terminateOnError(m_smoothType != NONE,
\r
217 "ERROR: you already set smoothness, or said you'll use member function setSmoothCost() to set Smoothness Costs");
\r
220 m_smoothType = ARRAY;
\r
222 /* allocate memory dinamiocally */
\r
223 m_smoothcost = (EnergyTermType *) new EnergyTermType[m_num_labels*m_num_labels];
\r
224 for ( int i(0); i < m_num_labels*m_num_labels; i++ )
\r
225 m_smoothcost[i] = V[i];
\r
226 // m_smoothcost = V;
\r
228 m_varying_weights = 0;
\r
232 /**************************************************************************************/
\r
233 void GCoptimization::setSmoothness(EnergyTermType* V,EnergyTermType* hCue, EnergyTermType* vCue)
\r
235 terminateOnError(m_smoothType != NONE,
\r
236 "ERROR: you already set smoothness, or said you'll use member function setSmoothCost() to set Smoothness Costs");
\r
238 terminateOnError(!m_grid_graph,
\r
239 "ERROR: for a grid graph, you can't use vertical and horizontal cues. Use setNeighbors() member function to encode spatially varying cues");
\r
241 m_varying_weights = 1;
\r
243 m_smoothType = ARRAY;
\r
245 /* allocate memory dinamiocally */
\r
247 m_smoothcost = (EnergyTermType *) new EnergyTermType[m_num_labels*m_num_labels];
\r
248 for ( i = 0; i < m_num_labels*m_num_labels; i++ )
\r
249 m_smoothcost[i] = V[i];
\r
251 m_vertWeights = (EnergyTermType *) new EnergyTermType[m_num_pixels];
\r
252 for ( i = 0; i < m_num_pixels; i++ )
\r
253 m_vertWeights[i] = vCue[i];
\r
255 m_horizWeights = (EnergyTermType *) new EnergyTermType[m_num_pixels];
\r
256 for ( i = 0; i < m_num_pixels; i++ )
\r
257 m_horizWeights[i] = hCue[i];
\r
259 //m_vertWeights = vCue;
\r
260 //m_horizWeights = hCue;
\r
261 //m_smoothcost = V;
\r
265 /**************************************************************************************/
\r
267 void GCoptimization::setSmoothness(smoothFnCoord horz_cost, smoothFnCoord vert_cost)
\r
270 terminateOnError(m_smoothType != NONE,
\r
271 "ERROR: you already set smoothness, or said you'll use member function setSmoothCost() to set Smoothness Costs");
\r
273 terminateOnError( !m_grid_graph,"Cannot use smoothness function based on coordinates for non-grid graph");
\r
275 m_smoothType = FUNCTION_COORD;
\r
276 m_horz_cost = horz_cost;
\r
277 m_vert_cost = vert_cost;
\r
280 /**************************************************************************************/
\r
282 void GCoptimization::setSmoothness(smoothFnPix cost)
\r
284 terminateOnError(m_smoothType != NONE,
\r
285 "ERROR: you already set smoothness, or said you'll use member function setSmoothCost() to set Smoothness Costs");
\r
287 m_smoothType = FUNCTION_PIX;
\r
288 m_smoothFnPix = cost;
\r
291 /**************************************************************************************/
\r
294 GCoptimization::SetAllLabels(const LabelType* labels)
\r
296 for( int i(0); i < m_num_pixels; i++ ) {
\r
297 terminateOnError( (labels[i]<0) || (labels[i]>=m_num_labels), "Wrong label value");
\r
298 m_labeling[i] = labels[i];
\r
301 /**************************************************************************************/
\r
303 GCoptimization::ExportLabels(LabelType* labels)
\r
305 for( int i(0); i < m_num_pixels; i++)
\r
306 labels[i] = m_labeling[i];
\r
309 /**************************************************************************************/
\r
310 GCoptimization::EnergyType GCoptimization::giveDataEnergy()
\r
312 if ( m_dataType == ARRAY)
\r
313 return(giveDataEnergyArray());
\r
314 else if ( m_dataType == FUNCTION_PIX )
\r
315 return(giveDataEnergyFnPix());
\r
316 else if (m_dataType == FUNCTION_COORD ) return(giveDataEnergyFnCoord());
\r
317 else terminateOnError(1,"Did not initialize the data costs yet");
\r
322 /**************************************************************************************/
\r
324 GCoptimization::EnergyType GCoptimization::giveDataEnergyArray()
\r
326 EnergyType eng = (EnergyType) 0;
\r
329 for ( int i = 0; i < m_num_pixels; i++ ) {
\r
331 if (m_labeling[i] != m_num_labels+1) {
\r
332 eng = eng + m_datacost(i,m_labeling[i]);
\r
333 // mexPrintf("node %d, label %d : %f \t (%f)\n", i, m_labeling[i], m_datacost(i,m_labeling[i]), eng);
\r
340 /**************************************************************************************/
\r
342 GCoptimization::EnergyType GCoptimization::giveDataEnergyFnPix()
\r
345 EnergyType eng = (EnergyType) 0;
\r
347 for ( int i = 0; i < m_num_pixels; i++ )
\r
348 eng = eng + m_dataFnPix(i,m_labeling[i]);
\r
352 /**************************************************************************************/
\r
354 GCoptimization::EnergyType GCoptimization::giveDataEnergyFnCoord()
\r
356 EnergyType eng = (EnergyType) 0;
\r
358 for ( int y = 0; y < m_height; y++ )
\r
359 for ( int x = 0; x < m_width; x++ )
\r
360 eng = eng + m_dataFnCoord(x,y,m_labeling[x+y*m_width]);
\r
366 /**************************************************************************************/
\r
368 GCoptimization::EnergyType GCoptimization::giveSmoothEnergy()
\r
371 if ( m_grid_graph )
\r
373 if ( m_smoothType == ARRAY )
\r
375 if (m_varying_weights) return(giveSmoothEnergy_G_ARRAY_VW());
\r
376 else return(giveSmoothEnergy_G_ARRAY());
\r
378 else if ( m_smoothType == FUNCTION_PIX ) return(giveSmoothEnergy_G_FnPix());
\r
379 else if ( m_smoothType == FUNCTION_COORD ) return(giveSmoothEnergy_G_FnCoord());
\r
380 else terminateOnError(1,"Did not initialize smoothness costs yet, can't compute smooth energy");
\r
384 if ( m_smoothType == ARRAY ) return(giveSmoothEnergy_NG_ARRAY());
\r
385 else if ( m_smoothType == FUNCTION_PIX ) return(giveSmoothEnergy_NG_FnPix());
\r
386 else terminateOnError(1,"Did not initialize smoothness costs yet, can't compute smooth energy");
\r
392 /**************************************************************************************/
\r
394 GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_NG_FnPix()
\r
397 EnergyType eng = (EnergyType) 0;
\r
401 for ( i = 0; i < m_num_pixels; i++ )
\r
402 if ( !m_neighbors[i].isEmpty() )
\r
404 m_neighbors[i].setCursorFront();
\r
405 while ( m_neighbors[i].hasNext() )
\r
407 temp = (Neighbor *) m_neighbors[i].next();
\r
408 if ( i < temp->to_node )
\r
409 eng = eng + m_smoothFnPix(i,temp->to_node, m_labeling[i],m_labeling[temp->to_node]);
\r
417 /**************************************************************************************/
\r
419 GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_NG_ARRAY()
\r
421 EnergyType eng = (EnergyType) 0;
\r
425 for ( i = 0; i < m_num_pixels; i++ )
\r
426 if ( !m_neighbors[i].isEmpty() )
\r
428 m_neighbors[i].setCursorFront();
\r
429 while ( m_neighbors[i].hasNext() )
\r
431 temp = (Neighbor *) m_neighbors[i].next();
\r
433 if ( i < temp->to_node )
\r
434 eng = eng + m_smoothcost(m_labeling[i],m_labeling[temp->to_node])*(temp->weight);
\r
442 /**************************************************************************************/
\r
444 GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_G_ARRAY_VW()
\r
447 EnergyType eng = (EnergyType) 0;
\r
450 // printf("\nIn right place");
\r
452 for ( y = 0; y < m_height; y++ )
\r
453 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) )
\r
456 eng = eng + m_smoothcost(m_labeling[pix],m_labeling[pix-1])*m_horizWeights[pix-1];
\r
459 for ( y = 1; y < m_height; y++ )
\r
460 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) )
\r
463 eng = eng + m_smoothcost(m_labeling[pix],m_labeling[pix-m_width])*m_vertWeights[pix-m_width];
\r
470 /**************************************************************************************/
\r
472 GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_G_ARRAY()
\r
475 EnergyType eng = (EnergyType) 0;
\r
479 for ( y = 0; y < m_height; y++ )
\r
480 for ( x = 1; x < m_width; x++ )
\r
483 eng = eng + m_smoothcost(m_labeling[pix],m_labeling[pix-1]);
\r
486 for ( y = 1; y < m_height; y++ )
\r
487 for ( x = 0; x < m_width; x++ )
\r
490 eng = eng + m_smoothcost(m_labeling[pix],m_labeling[pix-m_width]);
\r
496 /**************************************************************************************/
\r
498 GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_G_FnPix()
\r
501 EnergyType eng = (EnergyType) 0;
\r
505 for ( y = 0; y < m_height; y++ )
\r
506 for ( x = 1; x < m_width; x++ )
\r
509 eng = eng + m_smoothFnPix(pix,pix-1,m_labeling[pix],m_labeling[pix-1]);
\r
512 for ( y = 1; y < m_height; y++ )
\r
513 for ( x = 0; x < m_width; x++ )
\r
516 eng = eng + m_smoothFnPix(pix,pix-m_width,m_labeling[pix],m_labeling[pix-m_width]);
\r
522 /**************************************************************************************/
\r
524 GCoptimization::EnergyType GCoptimization::giveSmoothEnergy_G_FnCoord()
\r
527 EnergyType eng = (EnergyType) 0;
\r
531 for ( y = 0; y < m_height; y++ )
\r
532 for ( x = 1; x < m_width; x++ )
\r
535 eng = eng + m_horz_cost(x-1,y,m_labeling[pix],m_labeling[pix-1]);
\r
538 for ( y = 1; y < m_height; y++ )
\r
539 for ( x = 0; x < m_width; x++ )
\r
542 eng = eng + m_vert_cost(x,y-1,m_labeling[pix],m_labeling[pix-m_width]);
\r
549 /**************************************************************************************/
\r
551 GCoptimization::EnergyType GCoptimization::compute_energy()
\r
553 return(giveDataEnergy()+giveSmoothEnergy());
\r
556 /**************************************************************************************/
\r
558 GCoptimization::EnergyType GCoptimization::expansion(int max_num_iterations)
\r
560 return(start_expansion(max_num_iterations));
\r
563 /**************************************************************************************/
\r
566 GCoptimization::EnergyType GCoptimization::expansion()
\r
568 return(start_expansion(MAX_INTT));
\r
571 /**************************************************************************************/
\r
574 GCoptimization::EnergyType GCoptimization::start_expansion(int max_num_iterations )
\r
577 int curr_cycle = 1;
\r
578 EnergyType new_energy,old_energy;
\r
581 new_energy = compute_energy();
\r
583 old_energy = (new_energy+1)*10; // BAGON changed init value to exceed current energy by factor of 10 (thanks to A. Khan)
\r
585 while ( old_energy > new_energy && curr_cycle <= max_num_iterations)
\r
587 old_energy = new_energy;
\r
588 new_energy = oneExpansionIteration();
\r
593 return(new_energy);
\r
596 /****************************************************************************/
\r
598 void GCoptimization::scramble_label_table()
\r
600 LabelType r1,r2,temp;
\r
604 num_times = m_num_labels*2;
\r
606 for ( cnt = 0; cnt < num_times; cnt++ )
\r
608 r1 = rand()%m_num_labels;
\r
609 r2 = rand()%m_num_labels;
\r
611 temp = m_labelTable[r1];
\r
612 m_labelTable[r1] = m_labelTable[r2];
\r
613 m_labelTable[r2] = temp;
\r
617 /**************************************************************************************/
\r
619 GCoptimization::EnergyType GCoptimization::alpha_expansion(LabelType label)
\r
621 terminateOnError( label < 0 || label >= m_num_labels,"Illegal Label to Expand On");
\r
623 perform_alpha_expansion(label);
\r
624 return(compute_energy());
\r
627 /**************************************************************************************/
\r
629 GCoptimization::EnergyType GCoptimization::alpha_expansion(LabelType alpha_label, PixelType *pixels, int num )
\r
631 PixelType i,size = 0;
\r
632 Energy *e = new Energy(mexErrMsgTxt, truncate_flag);
\r
636 for ( i = 0; i<num ; i++ )
\r
638 if ( m_labeling[pixels[i]] != alpha_label )
\r
640 m_lookupPixVar[pixels[i]] = i;
\r
647 Energy::Var *variables = (Energy::Var *) new Energy::Var[size];
\r
649 for ( i = 0; i < size; i++ )
\r
650 variables[i] = e ->add_variable();
\r
652 if ( m_dataType == ARRAY ) add_t_links_ARRAY(e,variables,size,alpha_label);
\r
653 else if ( m_dataType == FUNCTION_PIX ) add_t_links_FnPix(e,variables,size,alpha_label);
\r
654 else add_t_links_FnCoord(e,variables,size,alpha_label);
\r
657 if ( m_grid_graph )
\r
659 if ( m_smoothType == ARRAY )
\r
661 if (m_varying_weights) set_up_expansion_energy_G_ARRAY_VW_pix(size,alpha_label,e,variables,pixels,num);
\r
662 else set_up_expansion_energy_G_ARRAY_pix(size,alpha_label,e,variables,pixels,num);
\r
664 else if ( m_smoothType == FUNCTION_PIX ) {
\r
665 mexErrMsgIdAndTxt("GraphCut:internal", "NOT SUPPORTED YET,exiting!");
\r
666 // printf("NOT SUPPORTED YET,exiting!");
\r
668 //if ( m_smoothType == FUNCTION_PIX ) set_up_expansion_energy_G_FnPix_pix(size,alpha_label,e,variables);
\r
672 mexErrMsgIdAndTxt("GraphCut:internal", "NOT SUPPORTED YET,exiting!");
\r
673 // printf("NOT SUPPORTED YET,exiting!");
\r
675 //set_up_expansion_energy_G_FnCoord_pix(size,alpha_label,e,variables);
\r
681 mexErrMsgIdAndTxt("GraphCut:internal", "NOT SUPPORTED YET,exiting!");
\r
682 // printf("NOT SUPPORTED YET,exiting!");
\r
684 /*if ( m_smoothType == ARRAY ) set_up_expansion_energy_NG_ARRAY_pix(size,alpha_label,e,variables);
\r
685 else if ( m_smoothType == FUNCTION_PIX ) set_up_expansion_energy_NG_FnPix_pix(size,alpha_label,e,variables);*/
\r
692 for ( i = 0; i < num; i++ )
\r
694 if ( m_labeling[pixels[i]] != alpha_label )
\r
696 if ( e->get_var(variables[i]) == 0 )
\r
697 m_labeling[pixels[i]] = alpha_label;
\r
699 m_lookupPixVar[pixels[i]] = -1;
\r
702 delete [] variables;
\r
707 return(compute_energy());
\r
710 /**************************************************************************************/
\r
712 void GCoptimization::add_t_links_ARRAY(Energy *e,Energy::Var *variables,int size,LabelType alpha_label)
\r
714 for ( int i = 0; i < size; i++ )
\r
715 e -> add_term1(variables[i], m_datacost(m_lookupPixVar[i],alpha_label),
\r
716 m_datacost(m_lookupPixVar[i],m_labeling[m_lookupPixVar[i]]));
\r
720 /**************************************************************************************/
\r
722 void GCoptimization::add_t_links_FnPix(Energy *e,Energy::Var *variables,int size,LabelType alpha_label)
\r
724 for ( int i = 0; i < size; i++ )
\r
725 e -> add_term1(variables[i], m_dataFnPix(m_lookupPixVar[i],alpha_label),
\r
726 m_dataFnPix(m_lookupPixVar[i],m_labeling[m_lookupPixVar[i]]));
\r
729 /**************************************************************************************/
\r
731 void GCoptimization::add_t_links_FnCoord(Energy *e,Energy::Var *variables,int size,LabelType alpha_label)
\r
735 for ( int i = 0; i < size; i++ )
\r
738 y = m_lookupPixVar[i]/m_width;
\r
739 x = m_lookupPixVar[i] - y*m_width;
\r
741 e -> add_term1(variables[i], m_dataFnCoord(x,y,alpha_label),
\r
742 m_dataFnCoord(x,y,m_labeling[m_lookupPixVar[i]]));
\r
747 /**************************************************************************************/
\r
749 void GCoptimization::perform_alpha_expansion(LabelType alpha_label)
\r
751 PixelType i,size = 0;
\r
752 Energy *e = new Energy(mexErrMsgTxt, truncate_flag);
\r
756 for ( i = 0; i < m_num_pixels; i++ )
\r
758 if ( m_labeling[i] != alpha_label )
\r
760 m_lookupPixVar[size] = i;
\r
768 Energy::Var *variables = (Energy::Var *) new Energy::Var[size];
\r
770 for ( i = 0; i < size; i++ )
\r
771 variables[i] = e ->add_variable();
\r
773 if ( m_dataType == ARRAY ) add_t_links_ARRAY(e,variables,size,alpha_label);
\r
774 else if ( m_dataType == FUNCTION_PIX ) add_t_links_FnPix(e,variables,size,alpha_label);
\r
775 else add_t_links_FnCoord(e,variables,size,alpha_label);
\r
778 if ( m_grid_graph )
\r
780 if ( m_smoothType == ARRAY )
\r
782 if (m_varying_weights) set_up_expansion_energy_G_ARRAY_VW(size,alpha_label,e,variables);
\r
783 else set_up_expansion_energy_G_ARRAY(size,alpha_label,e,variables);
\r
785 else if ( m_smoothType == FUNCTION_PIX ) set_up_expansion_energy_G_FnPix(size,alpha_label,e,variables);
\r
786 else set_up_expansion_energy_G_FnCoord(size,alpha_label,e,variables);
\r
791 if ( m_smoothType == ARRAY ) set_up_expansion_energy_NG_ARRAY(size,alpha_label,e,variables);
\r
792 else if ( m_smoothType == FUNCTION_PIX ) set_up_expansion_energy_NG_FnPix(size,alpha_label,e,variables);
\r
799 for ( i = 0,size = 0; i < m_num_pixels; i++ )
\r
801 if ( m_labeling[i] != alpha_label )
\r
803 if ( e->get_var(variables[size]) == 0 )
\r
804 m_labeling[i] = alpha_label;
\r
810 delete [] variables;
\r
816 /**********************************************************************************************/
\r
817 /* Performs alpha-expansion for non regular grid graph for case when energy terms are NOT */
\r
818 /* specified by a function */
\r
820 void GCoptimization::set_up_expansion_energy_NG_ARRAY(int size, LabelType alpha_label,Energy *e,Energy::Var *variables )
\r
822 EnergyTermType weight;
\r
828 for ( i = size - 1; i >= 0; i-- )
\r
830 pix = m_lookupPixVar[i];
\r
831 m_lookupPixVar[pix] = i;
\r
833 if ( !m_neighbors[pix].isEmpty() )
\r
835 m_neighbors[pix].setCursorFront();
\r
837 while ( m_neighbors[pix].hasNext() )
\r
839 tmp = (Neighbor *) (m_neighbors[pix].next());
\r
840 nPix = tmp->to_node;
\r
841 weight = tmp->weight;
\r
843 if ( m_labeling[nPix] != alpha_label )
\r
846 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
847 m_smoothcost(alpha_label,alpha_label)*weight,
\r
848 m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
849 m_smoothcost(m_labeling[pix],alpha_label)*weight,
\r
850 m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight);
\r
853 e ->add_term1(variables[i],m_smoothcost(alpha_label,alpha_label)*weight,
\r
854 m_smoothcost(m_labeling[pix],alpha_label)*weight);
\r
863 /**********************************************************************************************/
\r
864 /* Performs alpha-expansion for non regular grid graph for case when energy terms are */
\r
865 /* specified by a function */
\r
867 void GCoptimization::set_up_expansion_energy_NG_FnPix(int size, LabelType alpha_label,Energy *e,Energy::Var *variables )
\r
874 for ( i = size - 1; i >= 0; i-- )
\r
876 pix = m_lookupPixVar[i];
\r
877 m_lookupPixVar[pix] = i;
\r
880 if ( !m_neighbors[pix].isEmpty() )
\r
882 m_neighbors[pix].setCursorFront();
\r
884 while ( m_neighbors[pix].hasNext() )
\r
886 tmp = (Neighbor *) (m_neighbors[pix].next());
\r
887 nPix = tmp->to_node;
\r
889 if ( m_labeling[nPix] != alpha_label )
\r
892 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
893 m_smoothFnPix(pix,nPix,alpha_label,alpha_label),
\r
894 m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
895 m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label),
\r
896 m_smoothFnPix(pix,nPix,m_labeling[pix],m_labeling[nPix]));
\r
899 e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
900 m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label));
\r
907 /**********************************************************************************************/
\r
908 /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */
\r
909 /* specified by a function */
\r
910 void GCoptimization::set_up_expansion_energy_G_ARRAY_VW(int size, LabelType alpha_label,Energy *e,
\r
911 Energy::Var *variables )
\r
913 int i,nPix,pix,x,y;
\r
914 EnergyTermType weight;
\r
917 for ( i = size - 1; i >= 0; i-- )
\r
919 pix = m_lookupPixVar[i];
\r
921 x = pix - y*m_width;
\r
923 m_lookupPixVar[pix] = i;
\r
925 if ( x < m_width - 1 )
\r
928 weight = m_horizWeights[pix];
\r
929 if ( m_labeling[nPix] != alpha_label )
\r
930 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
931 m_smoothcost(alpha_label,alpha_label)*weight,
\r
932 m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
933 m_smoothcost(m_labeling[pix],alpha_label)*weight,
\r
934 m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight);
\r
935 else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
936 m_smoothcost(m_labeling[pix],alpha_label)*weight);
\r
939 if ( y < m_height - 1 )
\r
941 nPix = pix + m_width;
\r
942 weight = m_vertWeights[pix];
\r
943 if ( m_labeling[nPix] != alpha_label )
\r
944 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
945 m_smoothcost(alpha_label,alpha_label)*weight ,
\r
946 m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
947 m_smoothcost(m_labeling[pix],alpha_label)*weight ,
\r
948 m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight );
\r
949 else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
950 m_smoothcost(m_labeling[pix],alpha_label)*weight);
\r
956 if ( m_labeling[nPix] == alpha_label )
\r
957 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*m_horizWeights[nPix],
\r
958 m_smoothcost(m_labeling[pix],alpha_label)*m_horizWeights[nPix]);
\r
963 nPix = pix - m_width;
\r
965 if ( m_labeling[nPix] == alpha_label )
\r
966 e ->add_term1(variables[i],m_smoothcost(alpha_label,alpha_label)*m_vertWeights[nPix],
\r
967 m_smoothcost(m_labeling[pix],alpha_label)*m_vertWeights[nPix]);
\r
978 /**********************************************************************************************/
\r
979 /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */
\r
980 /* specified by a function */
\r
981 void GCoptimization::set_up_expansion_energy_G_ARRAY(int size, LabelType alpha_label,Energy *e,
\r
982 Energy::Var *variables )
\r
984 int i,nPix,pix,x,y;
\r
987 for ( i = size - 1; i >= 0; i-- )
\r
989 pix = m_lookupPixVar[i];
\r
991 x = pix - y*m_width;
\r
993 m_lookupPixVar[pix] = i;
\r
995 if ( x < m_width - 1 )
\r
999 if ( m_labeling[nPix] != alpha_label )
\r
1000 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1001 m_smoothcost(alpha_label,alpha_label),
\r
1002 m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1003 m_smoothcost(m_labeling[pix],alpha_label),
\r
1004 m_smoothcost(m_labeling[pix],m_labeling[nPix]));
\r
1005 else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1006 m_smoothcost(m_labeling[pix],alpha_label));
\r
1009 if ( y < m_height - 1 )
\r
1011 nPix = pix + m_width;
\r
1013 if ( m_labeling[nPix] != alpha_label )
\r
1014 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1015 m_smoothcost(alpha_label,alpha_label) ,
\r
1016 m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1017 m_smoothcost(m_labeling[pix],alpha_label) ,
\r
1018 m_smoothcost(m_labeling[pix],m_labeling[nPix]) );
\r
1019 else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1020 m_smoothcost(m_labeling[pix],alpha_label));
\r
1026 if ( m_labeling[nPix] == alpha_label )
\r
1027 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1028 m_smoothcost(m_labeling[pix],alpha_label) );
\r
1033 nPix = pix - m_width;
\r
1035 if ( m_labeling[nPix] == alpha_label )
\r
1036 e ->add_term1(variables[i],m_smoothcost(alpha_label,alpha_label),
\r
1037 m_smoothcost(m_labeling[pix],alpha_label));
\r
1044 /**********************************************************************************************/
\r
1045 /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */
\r
1046 /* specified by a function */
\r
1047 void GCoptimization::set_up_expansion_energy_G_ARRAY_VW_pix(int size, LabelType alpha_label,Energy *e,
\r
1048 Energy::Var *variables, PixelType *pixels, int num )
\r
1050 int i,nPix,pix,x,y;
\r
1051 EnergyTermType weight;
\r
1054 for ( i = 0; i < num; i++ )
\r
1057 if ( m_labeling[pix]!= alpha_label )
\r
1060 x = pix - y*m_width;
\r
1062 if ( x < m_width - 1 )
\r
1065 weight = m_horizWeights[pix];
\r
1066 if ( m_labeling[nPix] != alpha_label && m_lookupPixVar[nPix] != -1 )
\r
1067 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1068 m_smoothcost(alpha_label,alpha_label)*weight,
\r
1069 m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
1070 m_smoothcost(m_labeling[pix],alpha_label)*weight,
\r
1071 m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight);
\r
1072 else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
1073 m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight);
\r
1076 if ( y < m_height - 1 )
\r
1078 nPix = pix + m_width;
\r
1079 weight = m_vertWeights[pix];
\r
1080 if ( m_labeling[nPix] != alpha_label && m_lookupPixVar[nPix] != -1 )
\r
1081 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1082 m_smoothcost(alpha_label,alpha_label)*weight ,
\r
1083 m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
1084 m_smoothcost(m_labeling[pix],alpha_label)*weight ,
\r
1085 m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight );
\r
1086 else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
1087 m_smoothcost(m_labeling[pix],m_labeling[nPix])*weight);
\r
1093 if ( m_labeling[nPix] == alpha_label || m_lookupPixVar[nPix] == -1)
\r
1094 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*m_horizWeights[nPix],
\r
1095 m_smoothcost(m_labeling[pix],m_labeling[nPix])*m_horizWeights[nPix]);
\r
1100 nPix = pix - m_width;
\r
1102 if ( m_labeling[nPix] == alpha_label || m_lookupPixVar[nPix] == -1)
\r
1103 e ->add_term1(variables[i],m_smoothcost(alpha_label,alpha_label)*m_vertWeights[nPix],
\r
1104 m_smoothcost(m_labeling[pix],m_labeling[nPix])*m_vertWeights[nPix]);
\r
1111 /**********************************************************************************************/
\r
1112 /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */
\r
1113 /* specified by a function */
\r
1114 void GCoptimization::set_up_expansion_energy_G_ARRAY_pix(int size, LabelType alpha_label,Energy *e,
\r
1115 Energy::Var *variables, PixelType *pixels,
\r
1118 int i,nPix,pix,x,y;
\r
1121 for ( i = 0; i < num; i++ )
\r
1125 x = pix - y*m_width;
\r
1128 if ( m_labeling[pix]!= alpha_label )
\r
1130 if ( x < m_width - 1 )
\r
1134 if ( m_labeling[nPix] != alpha_label && m_lookupPixVar[pix] != -1)
\r
1135 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1136 m_smoothcost(alpha_label,alpha_label),
\r
1137 m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1138 m_smoothcost(m_labeling[pix],alpha_label),
\r
1139 m_smoothcost(m_labeling[pix],m_labeling[nPix]));
\r
1140 else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1141 m_smoothcost(m_labeling[pix],m_labeling[nPix]));
\r
1144 if ( y < m_height - 1 )
\r
1146 nPix = pix + m_width;
\r
1148 if ( m_labeling[nPix] != alpha_label && m_lookupPixVar[pix] != -1)
\r
1149 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1150 m_smoothcost(alpha_label,alpha_label) ,
\r
1151 m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1152 m_smoothcost(m_labeling[pix],alpha_label) ,
\r
1153 m_smoothcost(m_labeling[pix],m_labeling[nPix]) );
\r
1154 else e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1155 m_smoothcost(m_labeling[pix],m_labeling[nPix]));
\r
1161 if ( m_labeling[nPix] == alpha_label || m_lookupPixVar[nPix] == -1)
\r
1162 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1163 m_smoothcost(m_labeling[pix],m_labeling[nPix]) );
\r
1168 nPix = pix - m_width;
\r
1170 if ( m_labeling[nPix] == alpha_label || m_lookupPixVar[nPix] == -1)
\r
1171 e ->add_term1(variables[i],m_smoothcost(alpha_label,alpha_label),
\r
1172 m_smoothcost(m_labeling[pix],m_labeling[nPix]));
\r
1180 /**********************************************************************************************/
\r
1181 /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */
\r
1182 /* specified by a function */
\r
1183 void GCoptimization::set_up_expansion_energy_G_FnPix(int size, LabelType alpha_label,Energy *e,
\r
1184 Energy::Var *variables )
\r
1186 int i,nPix,pix,x,y;
\r
1189 for ( i = size - 1; i >= 0; i-- )
\r
1191 pix = m_lookupPixVar[i];
\r
1193 x = pix - y*m_width;
\r
1195 m_lookupPixVar[pix] = i;
\r
1197 if ( x < m_width - 1 )
\r
1201 if ( m_labeling[nPix] != alpha_label )
\r
1202 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1203 m_smoothFnPix(pix,nPix,alpha_label,alpha_label),
\r
1204 m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
1205 m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label),
\r
1206 m_smoothFnPix(pix,nPix,m_labeling[pix],m_labeling[nPix]));
\r
1207 else e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
1208 m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label));
\r
1211 if ( y < m_height - 1 )
\r
1213 nPix = pix + m_width;
\r
1215 if ( m_labeling[nPix] != alpha_label )
\r
1216 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1217 m_smoothFnPix(pix,nPix,alpha_label,alpha_label) ,
\r
1218 m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
1219 m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label) ,
\r
1220 m_smoothFnPix(pix,nPix,m_labeling[pix],m_labeling[nPix]) );
\r
1221 else e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
1222 m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label));
\r
1228 if ( m_labeling[nPix] == alpha_label )
\r
1229 e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
1230 m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label) );
\r
1235 nPix = pix - m_width;
\r
1237 if ( m_labeling[nPix] == alpha_label )
\r
1238 e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,alpha_label),
\r
1239 m_smoothFnPix(pix,nPix,m_labeling[pix],alpha_label));
\r
1246 /**********************************************************************************************/
\r
1247 /* Performs alpha-expansion for regular grid graph for case when energy terms are NOT */
\r
1248 /* specified by a function */
\r
1249 void GCoptimization::set_up_expansion_energy_G_FnCoord(int size, LabelType alpha_label,Energy *e,
\r
1250 Energy::Var *variables )
\r
1252 int i,nPix,pix,x,y;
\r
1255 for ( i = size - 1; i >= 0; i-- )
\r
1257 pix = m_lookupPixVar[i];
\r
1259 x = pix - y*m_width;
\r
1261 m_lookupPixVar[pix] = i;
\r
1263 if ( x < m_width - 1 )
\r
1267 if ( m_labeling[nPix] != alpha_label )
\r
1268 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1269 m_horz_cost(x,y,alpha_label,alpha_label),
\r
1270 m_horz_cost(x,y,alpha_label,m_labeling[nPix]),
\r
1271 m_horz_cost(x,y,m_labeling[pix],alpha_label),
\r
1272 m_horz_cost(x,y,m_labeling[pix],m_labeling[nPix]));
\r
1273 else e ->add_term1(variables[i],m_horz_cost(x,y,alpha_label,alpha_label),
\r
1274 m_horz_cost(x,y,m_labeling[pix],alpha_label));
\r
1277 if ( y < m_height - 1 )
\r
1279 nPix = pix + m_width;
\r
1281 if ( m_labeling[nPix] != alpha_label )
\r
1282 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1283 m_vert_cost(x,y,alpha_label,alpha_label) ,
\r
1284 m_vert_cost(x,y,alpha_label,m_labeling[nPix]),
\r
1285 m_vert_cost(x,y,m_labeling[pix],alpha_label) ,
\r
1286 m_vert_cost(x,y,m_labeling[pix],m_labeling[nPix]) );
\r
1287 else e ->add_term1(variables[i],m_vert_cost(x,y,alpha_label,alpha_label),
\r
1288 m_vert_cost(x,y,m_labeling[pix],alpha_label));
\r
1294 if ( m_labeling[nPix] == alpha_label )
\r
1295 e ->add_term1(variables[i],m_horz_cost(x-1,y,alpha_label,m_labeling[nPix]),
\r
1296 m_horz_cost(x-1,y,m_labeling[pix],alpha_label) );
\r
1301 nPix = pix - m_width;
\r
1303 if ( m_labeling[nPix] == alpha_label )
\r
1304 e ->add_term1(variables[i],m_vert_cost(x,y-1,alpha_label,alpha_label),
\r
1305 m_vert_cost(x,y-1,m_labeling[pix],alpha_label));
\r
1312 /**************************************************************************************/
\r
1314 GCoptimization::EnergyType GCoptimization::oneExpansionIteration()
\r
1318 terminateOnError( m_dataType == NONE,"You have to set up the data cost before running optimization");
\r
1319 terminateOnError( m_smoothType == NONE,"You have to set up the smoothness cost before running optimization");
\r
1321 if (m_random_label_order) scramble_label_table();
\r
1324 for (next = 0; next < m_num_labels; next++ )
\r
1325 perform_alpha_expansion(m_labelTable[next]);
\r
1328 return(compute_energy());
\r
1331 /**************************************************************************************/
\r
1333 void GCoptimization::setNeighbors(PixelType pixel1, int pixel2, EnergyTermType weight)
\r
1336 assert(pixel1 < m_num_pixels && pixel1 >= 0 && pixel2 < m_num_pixels && pixel2 >= 0);
\r
1337 assert(m_grid_graph == 0);
\r
1339 Neighbor *temp1 = (Neighbor *) new Neighbor;
\r
1340 Neighbor *temp2 = (Neighbor *) new Neighbor;
\r
1342 temp1->weight = weight;
\r
1343 temp1->to_node = pixel2;
\r
1345 temp2->weight = weight;
\r
1346 temp2->to_node = pixel1;
\r
1348 m_neighbors[pixel1].addFront(temp1);
\r
1349 m_neighbors[pixel2].addFront(temp2);
\r
1353 /**************************************************************************************/
\r
1355 void GCoptimization::setNeighbors(PixelType pixel1, int pixel2)
\r
1358 assert(pixel1 < m_num_pixels && pixel1 >= 0 && pixel2 < m_num_pixels && pixel2 >= 0);
\r
1359 assert(m_grid_graph == 0);
\r
1362 Neighbor *temp1 = (Neighbor *) new Neighbor;
\r
1363 Neighbor *temp2 = (Neighbor *) new Neighbor;
\r
1365 temp1->weight = (EnergyTermType) 1;
\r
1366 temp1->to_node = pixel2;
\r
1368 temp2->weight = (EnergyTermType) 1;
\r
1369 temp2->to_node = pixel1;
\r
1371 m_neighbors[pixel1].addFront(temp1);
\r
1372 m_neighbors[pixel2].addFront(temp2);
\r
1376 /**************************************************************************************/
\r
1378 GCoptimization::~GCoptimization()
\r
1382 // mexWarnMsgTxt("Calling destructor"); /* bagon added */
\r
1383 if ( m_dataType == ARRAY )
\r
1384 delete [] m_datacost;
\r
1385 if ( m_smoothType == ARRAY )
\r
1386 delete [] m_smoothcost;
\r
1387 if ( m_varying_weights == 1 ) {
\r
1388 delete [] m_vertWeights;
\r
1389 delete [] m_horizWeights;
\r
1393 if ( m_deleteLabeling )
\r
1394 delete [] m_labeling;
\r
1397 if ( m_dataInput == SET_INDIVIDUALLY )
\r
1398 delete [] m_datacost;
\r
1400 if ( m_smoothInput == SET_INDIVIDUALLY )
\r
1401 delete [] m_smoothcost;
\r
1403 if ( ! m_grid_graph )
\r
1404 delete [] m_neighbors;
\r
1407 delete [] m_labelTable;
\r
1408 delete [] m_lookupPixVar;
\r
1413 /**************************************************************************************/
\r
1415 GCoptimization::EnergyType GCoptimization::swap(int max_num_iterations)
\r
1417 return(start_swap(max_num_iterations));
\r
1420 /**************************************************************************************/
\r
1423 GCoptimization::EnergyType GCoptimization::swap()
\r
1425 return(start_swap(MAX_INTT));
\r
1428 /**************************************************************************************/
\r
1431 GCoptimization::EnergyType GCoptimization::start_swap(int max_num_iterations )
\r
1434 int curr_cycle = 1;
\r
1435 EnergyType new_energy,old_energy;
\r
1438 new_energy = compute_energy();
\r
1440 old_energy = (new_energy+1)*10; // BAGON changed init value to exceed current energy by factor of 10 (thanks to A. Khan)
\r
1442 while ( old_energy > new_energy && curr_cycle <= max_num_iterations)
\r
1444 old_energy = new_energy;
\r
1445 new_energy = oneSwapIteration();
\r
1450 return(new_energy);
\r
1453 /**************************************************************************************/
\r
1455 GCoptimization::EnergyType GCoptimization::oneSwapIteration()
\r
1459 if (m_random_label_order) scramble_label_table();
\r
1462 for (next = 0; next < m_num_labels; next++ )
\r
1463 for (next1 = m_num_labels - 1; next1 >= 0; next1-- )
\r
1464 if ( m_labelTable[next] < m_labelTable[next1] )
\r
1465 perform_alpha_beta_swap(m_labelTable[next],m_labelTable[next1]);
\r
1467 return(compute_energy());
\r
1470 /**************************************************************************************/
\r
1472 GCoptimization::EnergyType GCoptimization::alpha_beta_swap(LabelType alpha_label, LabelType beta_label)
\r
1474 terminateOnError( alpha_label < 0 || alpha_label >= m_num_labels || beta_label < 0 || beta_label >= m_num_labels,
\r
1475 "Illegal Label to Expand On");
\r
1476 perform_alpha_beta_swap(alpha_label,beta_label);
\r
1477 return(compute_energy());
\r
1479 /**************************************************************************************/
\r
1481 void GCoptimization::add_t_links_ARRAY_swap(Energy *e,Energy::Var *variables,int size,
\r
1482 LabelType alpha_label, LabelType beta_label,
\r
1483 PixelType *pixels)
\r
1485 for ( int i = 0; i < size; i++ )
\r
1486 e -> add_term1(variables[i], m_datacost(pixels[i],alpha_label),
\r
1487 m_datacost(pixels[i],beta_label));
\r
1491 /**************************************************************************************/
\r
1493 void GCoptimization::add_t_links_FnPix_swap(Energy *e,Energy::Var *variables,int size,
\r
1494 LabelType alpha_label, LabelType beta_label,
\r
1495 PixelType *pixels)
\r
1497 for ( int i = 0; i < size; i++ )
\r
1498 e -> add_term1(variables[i], m_dataFnPix(pixels[i],alpha_label),
\r
1499 m_dataFnPix(pixels[i],beta_label));
\r
1502 /**************************************************************************************/
\r
1504 void GCoptimization::add_t_links_FnCoord_swap(Energy *e,Energy::Var *variables,int size,
\r
1505 LabelType alpha_label, LabelType beta_label,
\r
1506 PixelType *pixels)
\r
1510 for ( int i = 0; i < size; i++ )
\r
1513 y = pixels[i]/m_width;
\r
1514 x = pixels[i] - y*m_width;
\r
1516 e -> add_term1(variables[i], m_dataFnCoord(x,y,alpha_label),m_dataFnCoord(x,y,beta_label));
\r
1521 /**************************************************************************************/
\r
1523 void GCoptimization::perform_alpha_beta_swap(LabelType alpha_label, LabelType beta_label)
\r
1525 PixelType i,size = 0;
\r
1526 Energy *e = new Energy(mexErrMsgTxt, truncate_flag);
\r
1527 PixelType *pixels = new PixelType[m_num_pixels];
\r
1530 for ( i = 0; i < m_num_pixels; i++ )
\r
1532 if ( m_labeling[i] == alpha_label || m_labeling[i] == beta_label)
\r
1535 m_lookupPixVar[i] = size;
\r
1548 Energy::Var *variables = (Energy::Var *) new Energy::Var[size];
\r
1551 for ( i = 0; i < size; i++ )
\r
1552 variables[i] = e ->add_variable();
\r
1554 if ( m_dataType == ARRAY ) add_t_links_ARRAY_swap(e,variables,size,alpha_label,beta_label,pixels);
\r
1555 else if ( m_dataType == FUNCTION_PIX ) add_t_links_FnPix_swap(e,variables,size,alpha_label,beta_label,pixels);
\r
1556 else add_t_links_FnCoord_swap(e,variables,size,alpha_label,beta_label,pixels);
\r
1560 if ( m_grid_graph )
\r
1562 if ( m_smoothType == ARRAY )
\r
1564 if (m_varying_weights) set_up_swap_energy_G_ARRAY_VW(size,alpha_label,beta_label,pixels,e,variables);
\r
1565 else set_up_swap_energy_G_ARRAY(size,alpha_label,beta_label,pixels,e,variables);
\r
1567 else if ( m_smoothType == FUNCTION_PIX ) set_up_swap_energy_G_FnPix(size,alpha_label,beta_label,pixels,e,variables);
\r
1568 else set_up_swap_energy_G_FnCoord(size,alpha_label,beta_label,pixels,e,variables);
\r
1573 if ( m_smoothType == ARRAY ) set_up_swap_energy_NG_ARRAY(size,alpha_label,beta_label,pixels,e,variables);
\r
1574 else if ( m_smoothType == FUNCTION_PIX ) set_up_swap_energy_NG_FnPix(size,alpha_label,beta_label,pixels,e,variables);
\r
1580 for ( i = 0; i < size; i++ )
\r
1581 if ( e->get_var(variables[i]) == 0 )
\r
1582 m_labeling[pixels[i]] = alpha_label;
\r
1583 else m_labeling[pixels[i]] = beta_label;
\r
1586 delete [] variables;
\r
1592 /**************************************************************************************/
\r
1594 void GCoptimization::set_up_swap_energy_NG_ARRAY(int size,LabelType alpha_label,LabelType beta_label,
\r
1595 PixelType *pixels,Energy* e, Energy::Var *variables)
\r
1597 PixelType nPix,pix,i;
\r
1598 EnergyTermType weight;
\r
1603 for ( i = 0; i < size; i++ )
\r
1606 if ( !m_neighbors[pix].isEmpty() )
\r
1608 m_neighbors[pix].setCursorFront();
\r
1610 while ( m_neighbors[pix].hasNext() )
\r
1612 tmp = (Neighbor *) (m_neighbors[pix].next());
\r
1613 nPix = tmp->to_node;
\r
1614 weight = tmp->weight;
\r
1616 if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label)
\r
1619 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1620 m_smoothcost(alpha_label,alpha_label)*weight,
\r
1621 m_smoothcost(alpha_label,beta_label)*weight,
\r
1622 m_smoothcost(beta_label,alpha_label)*weight,
\r
1623 m_smoothcost(beta_label,beta_label)*weight);
\r
1626 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
1627 m_smoothcost(beta_label,m_labeling[nPix])*weight);
\r
1633 /**************************************************************************************/
\r
1635 void GCoptimization::set_up_swap_energy_NG_FnPix(int size,LabelType alpha_label,LabelType beta_label,
\r
1636 PixelType *pixels,Energy* e, Energy::Var *variables)
\r
1638 PixelType nPix,pix,i;
\r
1642 for ( i = 0; i < size; i++ )
\r
1645 if ( !m_neighbors[pix].isEmpty() )
\r
1647 m_neighbors[pix].setCursorFront();
\r
1649 while ( m_neighbors[pix].hasNext() )
\r
1651 tmp = (Neighbor *) (m_neighbors[pix].next());
\r
1652 nPix = tmp->to_node;
\r
1654 if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label)
\r
1657 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1658 m_smoothFnPix(pix,nPix,alpha_label,alpha_label),
\r
1659 m_smoothFnPix(pix,nPix,alpha_label,beta_label),
\r
1660 m_smoothFnPix(pix,nPix,beta_label,alpha_label),
\r
1661 m_smoothFnPix(pix,nPix,beta_label,beta_label) );
\r
1664 e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
1665 m_smoothFnPix(pix,nPix,beta_label,m_labeling[nPix]));
\r
1671 /**************************************************************************************/
\r
1673 void GCoptimization::set_up_swap_energy_G_FnPix(int size,LabelType alpha_label,LabelType beta_label,
\r
1674 PixelType *pixels,Energy* e, Energy::Var *variables)
\r
1676 PixelType nPix,pix,i,x,y;
\r
1679 for ( i = 0; i < size; i++ )
\r
1683 x = pix - y*m_width;
\r
1689 if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label)
\r
1690 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1691 m_smoothFnPix(pix,nPix,alpha_label,alpha_label),
\r
1692 m_smoothFnPix(pix,nPix,alpha_label,beta_label),
\r
1693 m_smoothFnPix(pix,nPix,beta_label,alpha_label),
\r
1694 m_smoothFnPix(pix,nPix,beta_label,beta_label) );
\r
1697 e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
1698 m_smoothFnPix(pix,nPix,beta_label,m_labeling[nPix]));
\r
1703 nPix = pix - m_width;
\r
1704 if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label)
\r
1705 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1706 m_smoothFnPix(pix,nPix,alpha_label,alpha_label),
\r
1707 m_smoothFnPix(pix,nPix,alpha_label,beta_label),
\r
1708 m_smoothFnPix(pix,nPix,beta_label,alpha_label),
\r
1709 m_smoothFnPix(pix,nPix,beta_label,beta_label) );
\r
1712 e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
1713 m_smoothFnPix(pix,nPix,beta_label,m_labeling[nPix]));
\r
1716 if ( x < m_width - 1 )
\r
1720 if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) )
\r
1721 e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
1722 m_smoothFnPix(pix,nPix,beta_label,m_labeling[nPix]));
\r
1725 if ( y < m_height - 1 )
\r
1727 nPix = pix + m_width;
\r
1729 if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) )
\r
1730 e ->add_term1(variables[i],m_smoothFnPix(pix,nPix,alpha_label,m_labeling[nPix]),
\r
1731 m_smoothFnPix(pix,nPix,beta_label,m_labeling[nPix]));
\r
1736 /**************************************************************************************/
\r
1738 void GCoptimization::set_up_swap_energy_G_FnCoord(int size,LabelType alpha_label,LabelType beta_label,PixelType *pixels,
\r
1739 Energy* e, Energy::Var *variables)
\r
1741 PixelType nPix,pix,i,x,y;
\r
1744 for ( i = 0; i < size; i++ )
\r
1748 x = pix - y*m_width;
\r
1754 if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label)
\r
1755 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1756 m_horz_cost(x-1,y,alpha_label,alpha_label),
\r
1757 m_horz_cost(x-1,y,alpha_label,beta_label),
\r
1758 m_horz_cost(x-1,y,beta_label,alpha_label),
\r
1759 m_horz_cost(x-1,y,beta_label,beta_label) );
\r
1762 e ->add_term1(variables[i],m_horz_cost(x-1,y,alpha_label,m_labeling[nPix]),
\r
1763 m_horz_cost(x-1,y,beta_label,m_labeling[nPix]));
\r
1768 nPix = pix - m_width;
\r
1769 if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label)
\r
1770 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1771 m_vert_cost(x,y-1,alpha_label,alpha_label),
\r
1772 m_vert_cost(x,y-1,alpha_label,beta_label),
\r
1773 m_vert_cost(x,y-1,beta_label,alpha_label),
\r
1774 m_vert_cost(x,y-1,beta_label,beta_label) );
\r
1777 e ->add_term1(variables[i],m_vert_cost(x,y-1,alpha_label,m_labeling[nPix]),
\r
1778 m_vert_cost(x,y-1,beta_label,m_labeling[nPix]));
\r
1781 if ( x < m_width - 1 )
\r
1785 if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) )
\r
1786 e ->add_term1(variables[i],m_horz_cost(x,y,alpha_label,m_labeling[nPix]),
\r
1787 m_horz_cost(x,y,beta_label,m_labeling[nPix]));
\r
1790 if ( y < m_height - 1 )
\r
1792 nPix = pix + m_width;
\r
1794 if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) )
\r
1795 e ->add_term1(variables[i],m_vert_cost(x,y,alpha_label,m_labeling[nPix]),
\r
1796 m_vert_cost(x,y,beta_label,m_labeling[nPix]));
\r
1802 /**************************************************************************************/
\r
1804 void GCoptimization::set_up_swap_energy_G_ARRAY_VW(int size,LabelType alpha_label,LabelType beta_label,
\r
1805 PixelType *pixels,Energy* e, Energy::Var *variables)
\r
1807 PixelType nPix,pix,i,x,y;
\r
1808 EnergyTermType weight;
\r
1812 for ( i = 0; i < size; i++ )
\r
1816 x = pix - y*m_width;
\r
1821 weight = m_horizWeights[nPix];
\r
1823 if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label)
\r
1824 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1825 m_smoothcost(alpha_label,alpha_label)*weight,
\r
1826 m_smoothcost(alpha_label,beta_label)*weight,
\r
1827 m_smoothcost(beta_label,alpha_label)*weight,
\r
1828 m_smoothcost(beta_label,beta_label)*weight );
\r
1831 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
1832 m_smoothcost(beta_label,m_labeling[nPix])*weight);
\r
1837 nPix = pix - m_width;
\r
1838 weight = m_vertWeights[nPix];
\r
1840 if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label)
\r
1841 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1842 m_smoothcost(alpha_label,alpha_label)*weight,
\r
1843 m_smoothcost(alpha_label,beta_label)*weight,
\r
1844 m_smoothcost(beta_label,alpha_label)*weight,
\r
1845 m_smoothcost(beta_label,beta_label)*weight );
\r
1848 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*weight,
\r
1849 m_smoothcost(beta_label,m_labeling[nPix])*weight);
\r
1852 if ( x < m_width - 1 )
\r
1856 if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) )
\r
1857 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*m_horizWeights[pix],
\r
1858 m_smoothcost(beta_label,m_labeling[nPix])*m_horizWeights[pix]);
\r
1861 if ( y < m_height - 1 )
\r
1863 nPix = pix + m_width;
\r
1865 if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) )
\r
1866 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix])*m_vertWeights[pix],
\r
1867 m_smoothcost(beta_label,m_labeling[nPix])*m_vertWeights[pix]);
\r
1873 /**************************************************************************************/
\r
1875 void GCoptimization::set_up_swap_energy_G_ARRAY(int size,LabelType alpha_label,LabelType beta_label,
\r
1876 PixelType *pixels,Energy* e, Energy::Var *variables)
\r
1879 PixelType nPix,pix,i,x,y;
\r
1883 for ( i = 0; i < size; i++ )
\r
1887 x = pix - y*m_width;
\r
1894 if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label)
\r
1895 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1896 m_smoothcost(alpha_label,alpha_label),
\r
1897 m_smoothcost(alpha_label,beta_label),
\r
1898 m_smoothcost(beta_label,alpha_label),
\r
1899 m_smoothcost(beta_label,beta_label) );
\r
1902 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1903 m_smoothcost(beta_label,m_labeling[nPix]));
\r
1908 nPix = pix - m_width;
\r
1910 if ( m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label)
\r
1911 e ->add_term2(variables[i],variables[m_lookupPixVar[nPix]],
\r
1912 m_smoothcost(alpha_label,alpha_label),
\r
1913 m_smoothcost(alpha_label,beta_label),
\r
1914 m_smoothcost(beta_label,alpha_label),
\r
1915 m_smoothcost(beta_label,beta_label) );
\r
1918 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1919 m_smoothcost(beta_label,m_labeling[nPix]));
\r
1922 if ( x < m_width - 1 )
\r
1926 if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label) )
\r
1927 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1928 m_smoothcost(beta_label,m_labeling[nPix]));
\r
1931 if ( y < m_height - 1 )
\r
1933 nPix = pix + m_width;
\r
1935 if ( !(m_labeling[nPix] == alpha_label || m_labeling[nPix] == beta_label))
\r
1936 e ->add_term1(variables[i],m_smoothcost(alpha_label,m_labeling[nPix]),
\r
1937 m_smoothcost(beta_label,m_labeling[nPix]));
\r
1944 /**************************************************************************************/
\r
1946 void GCoptimization::setLabelOrder(bool RANDOM_LABEL_ORDER)
\r
1948 m_random_label_order = RANDOM_LABEL_ORDER;
\r
1951 /****************************************************************************/
\r
1952 /* This procedure checks if an error has occured, terminates program if yes */
\r
1954 void GCoptimization::terminateOnError(bool error_condition,const char *message)
\r
1957 if (error_condition)
\r
1959 mexErrMsgIdAndTxt("GraphCut:internal_error","\nGCoptimization error: %s\n", message);
\r