📄 gcoptimization.cpp
字号:
}
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);
}
/**************************************************************************************/
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);
}
}
/****************************************************************************/
void GCoptimization::clearAnswer()
{
if (!m_labeling ) {printf("First initialize algorithm" );exit(0);}
memset(m_labeling, 0, m_nPixels*sizeof(Label));
}
/****************************************************************************/
void GCoptimization::scramble_label_table()
{
LabelType r1,r2,temp;
int num_times,cnt;
num_times = m_nLabels*2;
srand(clock());
for ( cnt = 0; cnt < num_times; cnt++ )
{
r1 = rand()%m_nLabels;
r2 = rand()%m_nLabels;
temp = m_labelTable[r1];
m_labelTable[r1] = m_labelTable[r2];
m_labelTable[r2] = temp;
}
}
/**************************************************************************************/
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::setNeighbors(PixelType pixel1, int pixel2, EnergyTermType weight)
{
assert(pixel1 < m_nPixels && pixel1 >= 0 && pixel2 < m_nPixels && 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);
}
/**************************************************************************************/
GCoptimization::~GCoptimization()
{
delete [] m_labeling;
if ( ! m_grid_graph ) delete [] m_neighbors;
delete [] m_labelTable;
delete [] m_lookupPixVar;
if (m_needToFreeV) delete [] m_smoothcost;
}
/**************************************************************************************/
Swap::Swap(PixelType width,PixelType height,int num_labels, EnergyFunction *eng):GCoptimization(width,height,num_labels,eng)
{
m_pixels = new PixelType[m_nPixels];
terminateOnError( !m_pixels ,"Not enough memory");
}
/**************************************************************************************/
Swap::Swap(PixelType nPixels, int num_labels, EnergyFunction *eng):GCoptimization(nPixels,num_labels,eng)
{
m_pixels = new PixelType[m_nPixels];
terminateOnError( !m_pixels ,"Not enough memory");
}
/**************************************************************************************/
Swap::~Swap()
{
delete [] m_pixels;
}
/**************************************************************************************/
GCoptimization::EnergyType Swap::swap(int max_num_iterations)
{
return(start_swap(max_num_iterations));
}
/**************************************************************************************/
GCoptimization::EnergyType Swap::swap()
{
return(start_swap(MAX_INTT));
}
/**************************************************************************************/
GCoptimization::EnergyType Swap::start_swap(int max_num_iterations )
{
int curr_cycle = 1;
EnergyType new_energy,old_energy;
new_energy = dataEnergy()+smoothnessEnergy();
old_energy = new_energy+1;
while ( old_energy > new_energy && curr_cycle <= max_num_iterations)
{
old_energy = new_energy;
new_energy = oneSwapIteration();
curr_cycle++;
}
//printf(" swap energy %d",new_energy);
return(new_energy);
}
/**************************************************************************************/
GCoptimization::EnergyType Swap::oneSwapIteration()
{
int next,next1;
if (m_random_label_order) scramble_label_table();
for (next = 0; next < m_nLabels; next++ )
for (next1 = m_nLabels - 1; next1 >= 0; next1-- )
if ( m_labelTable[next] < m_labelTable[next1] )
{
perform_alpha_beta_swap(m_labelTable[next],m_labelTable[next1]);
}
return(dataEnergy()+smoothnessEnergy());
}
/**************************************************************************************/
GCoptimization::EnergyType Swap::alpha_beta_swap(LabelType alpha_label, LabelType beta_label)
{
terminateOnError( alpha_label < 0 || alpha_label >= m_nLabels || beta_label < 0 || beta_label >= m_nLabels,
"Illegal Label to Expand On");
perform_alpha_beta_swap(alpha_label,beta_label);
return(dataEnergy()+smoothnessEnergy());
}
/**************************************************************************************/
void Swap::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 Swap::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 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 Swap::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 Swap::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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -