example.cpp_
//////////////////////////////////////////////////////////////////////////////
// Example illustrating the use of GCoptimization.cpp
//
/////////////////////////////////////////////////////////////////////////////
//
// Optimization problem:
// is a set of sites (pixels) of width 10 and hight 5. Thus number of pixels is 50
// grid neighborhood: each pixel has its left, right, up, and bottom pixels as neighbors
// 7 labels
// Data costs: D(pixel,label) = 0 if pixel < 25 and label = 0
// : D(pixel,label) = 10 if pixel < 25 and label is not 0
// : D(pixel,label) = 0 if pixel >= 25 and label = 5
// : D(pixel,label) = 10 if pixel >= 25 and label is not 5
// Smoothness costs: V(p1,p2,l1,l2) = min( (l1-l2)*(l1-l2) , 4 )
// Below in the main program, we illustrate different ways of setting data and smoothness costs
// that our interface allow and solve this optimizaiton problem
// For most of the examples, we use no spatially varying pixel dependent terms.
// For some examples, to demonstrate spatially varying terms we use
// V(p1,p2,l1,l2) = w_{p1,p2}*[min((l1-l2)*(l1-l2),4)], with
// w_{p1,p2} = p1+p2 if |p1-p2| == 1 and w_{p1,p2} = p1*p2 if |p1-p2| is not 1
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include "GCoptimization.h"
struct ForDataFn{
int numLab;
int *data;
};
int smoothFn(int p1, int p2, int l1, int l2)
{
if ( (l1-l2)*(l1-l2) <= 4 ) return((l1-l2)*(l1-l2));
else return(4);
}
int dataFn(int p, int l, void *data)
{
ForDataFn *myData = (ForDataFn *) data;
int numLab = myData->numLab;
return( myData->data[p*numLab+l] );
}
////////////////////////////////////////////////////////////////////////////////
// smoothness and data costs are set up one by one, individually
// grid neighborhood structure is assumed
//
void GridGraph_Individually(int width,int height,int num_pixels,int num_labels)
{
int *result = new int[num_pixels]; // stores result of optimization
try{
GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width,height,num_labels);
// first set up data costs individually
for ( int i = 0; i < num_pixels; i++ )
for (int l = 0; l < num_labels; l++ )
if (i < 25 ){
if( l == 0 ) gc->setDataCost(i,l,0);
else gc->setDataCost(i,l,10);
}
else {
if( l == 5 ) gc->setDataCost(i,l,0);
else gc->setDataCost(i,l,10);
}
// next set up smoothness costs individually
for ( int l1 = 0; l1 < num_labels; l1++ )
for (int l2 = 0; l2 < num_labels; l2++ ){
int cost = (l1-l2)*(l1-l2) <= 4 ? (l1-l2)*(l1-l2):4;
gc->setSmoothCost(l1,l2,cost);
}
printf("\nBefore optimization energy is %d",gc->compute_energy());
gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
printf("\nAfter optimization energy is %d",gc->compute_energy());
for ( int i = 0; i < num_pixels; i++ )
result[i] = gc->whatLabel(i);
delete gc;
}
catch (GCException e){
e.Report();
}
delete [] result;
}
////////////////////////////////////////////////////////////////////////////////
// in this version, set data and smoothness terms using arrays
// grid neighborhood structure is assumed
//
void GridGraph_DArraySArray(int width,int height,int num_pixels,int num_labels)
{
int *result = new int[num_pixels]; // stores result of optimization
// first set up the array for data costs
int *data = new int[num_pixels*num_labels];
for ( int i = 0; i < num_pixels; i++ )
for (int l = 0; l < num_labels; l++ )
if (i < 25 ){
if( l == 0 ) data[i*num_labels+l] = 0;
else data[i*num_labels+l] = 10;
}
else {
if( l == 5 ) data[i*num_labels+l] = 0;
else data[i*num_labels+l] = 10;
}
// next set up the array for smooth costs
int *smooth = new int[num_labels*num_labels];
for ( int l1 = 0; l1 < num_labels; l1++ )
for (int l2 = 0; l2 < num_labels; l2++ )
smooth[l1+l2*num_labels] = (l1-l2)*(l1-l2) <= 4 ? (l1-l2)*(l1-l2):4;
try{
GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width,height,num_labels);
gc->setDataCost(data);
gc->setSmoothCost(smooth);
printf("\nBefore optimization energy is %d",gc->compute_energy());
gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
printf("\nAfter optimization energy is %d",gc->compute_energy());
for ( int i = 0; i < num_pixels; i++ )
result[i] = gc->whatLabel(i);
delete gc;
}
catch (GCException e){
e.Report();
}
delete [] result;
delete [] smooth;
delete [] data;
}
////////////////////////////////////////////////////////////////////////////////
// in this version, set data and smoothness terms using arrays
// grid neighborhood structure is assumed
//
void GridGraph_DfnSfn(int width,int height,int num_pixels,int num_labels)
{
int *result = new int[num_pixels]; // stores result of optimization
// first set up the array for data costs
int *data = new int[num_pixels*num_labels];
for ( int i = 0; i < num_pixels; i++ )
for (int l = 0; l < num_labels; l++ )
zif (i < 25 ){
if( l == 0 ) data[i*num_labels+l] = 0;
else data[i*num_labels+l] = 10;
}
else {
if( l == 5 ) data[i*num_labels+l] = 0;
else data[i*num_labels+l] = 10;
}
try{
GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width,height,num_labels);
// set up the needed data to pass to function for the data costs
ForDataFn toFn;
toFn.data = data;
toFn.numLab = num_labels;
gc->setDataCost(&dataFn,&toFn);
// smoothness comes from function pointer
gc->setSmoothCost(&smoothFn);
printf("\nBefore optimization energy is %d",gc->compute_energy());
gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
printf("\nAfter optimization energy is %d",gc->compute_energy());
for ( int i = 0; i < num_pixels; i++ )
result[i] = gc->whatLabel(i);
delete gc;
}
catch (GCException e){
e.Report();
}
delete [] result;
delete [] data;
}
////////////////////////////////////////////////////////////////////////////////
// Uses spatially varying smoothness terms. That is
// V(p1,p2,l1,l2) = w_{p1,p2}*[min((l1-l2)*(l1-l2),4)], with
// w_{p1,p2} = p1+p2 if |p1-p2| == 1 and w_{p1,p2} = p1*p2 if |p1-p2| is not 1
void GridGraph_DArraySArraySpatVarying(int width,int height,int num_pixels,int num_labels)
{
int *result = new int[num_pixels]; // stores result of optimization
// first set up the array for data costs
int *data = new int[num_pixels*num_labels];
for ( int i = 0; i < num_pixels; i++ )
for (int l = 0; l < num_labels; l++ )
if (i < 25 ){
if( l == 0 ) data[i*num_labels+l] = 0;
else data[i*num_labels+l] = 10;
}
else {
if( l == 5 ) data[i*num_labels+l] = 0;
else data[i*num_labels+l] = 10;
}
// next set up the array for smooth costs
int *smooth = new int[num_labels*num_labels];
for ( int l1 = 0; l1 < num_labels; l1++ )
for (int l2 = 0; l2 < num_labels; l2++ )
smooth[l1+l2*num_labels] = (l1-l2)*(l1-l2) <= 4 ? (l1-l2)*(l1-l2):4;
// next set up spatially varying arrays V and H
int *V = new int[num_pixels];
int *H = new int[num_pixels];
for ( int i = 0; i < num_pixels; i++ ){
H[i] = i+(i+1)%3;
V[i] = i*(i+width)%7;
}
try{
GCoptimizationGridGraph *gc = new GCoptimizationGridGraph(width,height,num_labels);
gc->setDataCost(data);
gc->setSmoothCostVH(smooth,V,H);
printf("\nBefore optimization energy is %d",gc->compute_energy());
gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
printf("\nAfter optimization energy is %d",gc->compute_energy());
for ( int i = 0; i < num_pixels; i++ )
result[i] = gc->whatLabel(i);
delete gc;
}
catch (GCException e){
e.Report();
}
delete [] result;
delete [] smooth;
delete [] data;
}
////////////////////////////////////////////////////////////////////////////////
// in this version, set data and smoothness terms using arrays
// grid neighborhood is set up "manually"
//
void GeneralGraph_DArraySArray(int width,int height,int num_pixels,int num_labels)
{
int *result = new int[num_pixels]; // stores result of optimization
// first set up the array for data costs
int *data = new int[num_pixels*num_labels];
for ( int i = 0; i < num_pixels; i++ )
for (int l = 0; l < num_labels; l++ )
if (i < 25 ){
if( l == 0 ) data[i*num_labels+l] = 0;
else data[i*num_labels+l] = 10;
}
else {
if( l == 5 ) data[i*num_labels+l] = 0;
else data[i*num_labels+l] = 10;
}
// next set up the array for smooth costs
int *smooth = new int[num_labels*num_labels];
for ( int l1 = 0; l1 < num_labels; l1++ )
for (int l2 = 0; l2 < num_labels; l2++ )
smooth[l1+l2*num_labels] = (l1-l2)*(l1-l2) <= 4 ? (l1-l2)*(l1-l2):4;
try{
GCoptimizationGeneralGraph *gc = new GCoptimizationGeneralGraph(num_pixels,num_labels);
gc->setDataCost(data);
gc->setSmoothCost(smooth);
// now set up a grid neighborhood system
// first set up horizontal neighbors
for (int y = 0; y < height; y++ )
for (int x = 1; x < width; x++ )
gc->setNeighbors(x+y*width,x-1+y*width);
// next set up vertical neighbors
for (int y = 1; y < height; y++ )
for (int x = 0; x < width; x++ )
gc->setNeighbors(x+y*width,x+(y-1)*width);
printf("\nBefore optimization energy is %d",gc->compute_energy());
gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
printf("\nAfter optimization energy is %d",gc->compute_energy());
for ( int i = 0; i < num_pixels; i++ )
result[i] = gc->whatLabel(i);
delete gc;
}
catch (GCException e){
e.Report();
}
delete [] result;
delete [] smooth;
delete [] data;
}
////////////////////////////////////////////////////////////////////////////////
// in this version, set data and smoothness terms using arrays
// grid neighborhood is set up "manually". Uses spatially varying terms. Namely
// V(p1,p2,l1,l2) = w_{p1,p2}*[min((l1-l2)*(l1-l2),4)], with
// w_{p1,p2} = p1+p2 if |p1-p2| == 1 and w_{p1,p2} = p1*p2 if |p1-p2| is not 1
void GeneralGraph_DArraySArraySpatVarying(int width,int height,int num_pixels,int num_labels)
{
int *result = new int[num_pixels]; // stores result of optimization
// first set up the array for data costs
int *data = new int[num_pixels*num_labels];
for ( int i = 0; i < num_pixels; i++ )
for (int l = 0; l < num_labels; l++ )
if (i < 25 ){
if( l == 0 ) data[i*num_labels+l] = 0;
else data[i*num_labels+l] = 10;
}
else {
if( l == 5 ) data[i*num_labels+l] = 0;
else data[i*num_labels+l] = 10;
}
// next set up the array for smooth costs
int *smooth = new int[num_labels*num_labels];
for ( int l1 = 0; l1 < num_labels; l1++ )
for (int l2 = 0; l2 < num_labels; l2++ )
smooth[l1+l2*num_labels] = (l1-l2)*(l1-l2) <= 4 ? (l1-l2)*(l1-l2):4;
try{
GCoptimizationGeneralGraph *gc = new GCoptimizationGeneralGraph(num_pixels,num_labels);
gc->setDataCost(data);
gc->setSmoothCost(smooth);
// now set up a grid neighborhood system
// first set up horizontal neighbors
for (int y = 0; y < height; y++ )
for (int x = 1; x < width; x++ ){
int p1 = x-1+y*width;
int p2 =x+y*width;
gc->setNeighbors(p1,p2,p1+p2);
}
// next set up vertical neighbors
for (int y = 1; y < height; y++ )
for (int x = 0; x < width; x++ ){
int p1 = x+(y-1)*width;
int p2 =x+y*width;
gc->setNeighbors(p1,p2,p1*p2);
}
printf("\nBefore optimization energy is %d",gc->compute_energy());
gc->expansion(2);// run expansion for 2 iterations. For swap use gc->swap(num_iterations);
printf("\nAfter optimization energy is %d",gc->compute_energy());
for ( int i = 0; i < num_pixels; i++ )
result[i] = gc->whatLabel(i);
delete gc;
}
catch (GCException e){
e.Report();
}
delete [] result;
delete [] smooth;
delete [] data;
}
////////////////////////////////////////////////////////////////////////////////
int main_(int argc, char **argv)
{
int width = 10;
int height = 5;
int num_pixels = width*height;
int num_labels = 7;
// smoothness and data costs are set up one by one, individually
GridGraph_Individually(width,height,num_pixels,num_labels);
// smoothness and data costs are set up using arrays
GridGraph_DArraySArray(width,height,num_pixels,num_labels);
// smoothness and data costs are set up using functions
GridGraph_DfnSfn(width,height,num_pixels,num_labels);
// smoothness and data costs are set up using arrays.
// spatially varying terms are present
GridGraph_DArraySArraySpatVarying(width,height,num_pixels,num_labels);
//Will pretend our graph is
//general, and set up a neighborhood system
// which actually is a grid
GeneralGraph_DArraySArray(width,height,num_pixels,num_labels);
//Will pretend our graph is general, and set up a neighborhood system
// which actually is a grid. Also uses spatially varying terms
GeneralGraph_DArraySArraySpatVarying(width,height,num_pixels,num_labels);
printf("\n Finished %d (%d) clock per sec %d",clock()/CLOCKS_PER_SEC,clock(),CLOCKS_PER_SEC);
return 0;
}
/////////////////////////////////////////////////////////////////////////////////