📄 gcoptimization.cpp
字号:
// GCoptimization.cpp: implementation of the GCoptimization class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GraphCut.h"
#include "Energy.h"
#include "Graph.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include "GCoptimization.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#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;
}
/**************************************************************************************/
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;
initialize_memory();
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++ )
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;
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])*m_horizWeights[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])*m_vertWeights[pix-m_width];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -