⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gcoptimization.cpp

📁 GraphCut Minimization Library 转换成 VC++6.0 Class File
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// 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 + -