123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- /* Copyright Olga Veksler, Ramin Zabih, Vladimir Kolmogorov, and Daniel Scharstein
- * Send any questions to schar@middlebury.edu
- */
- #ifndef __MRF_H__
- #define __MRF_H__
- #include <stdio.h>
- namespace OBJREC {
- class EnergyFunction;
- class MRF
- {
- public:
- // *********** CONSTRUCTORS/DESTRUCTOR
- // Constructor. After you call this, you must call setData and setSmoothness
- // Use this constructor for 2D grid graphs of size width by height Standard 4-connected
- // neighborhood system is assumed. Labels are in the range 0,1,...nLabels - 1
- // Width is in the range 0,1,...width-1 and height is in the range 0,1,...height-1
- // Input parameter eng specifies the data and smoothness parts of the energy
- // For 2D grids, since 4 connected neighborhood structure is assumed, this
- // fully specifies the energy
- MRF(int width, int height, int nLabels, EnergyFunction *eng);
- // Use this constructor for a general neighborhood system. Pixels are in the range
- // 0,1,..nPixels-1, and labels are in the range 0,1,...,nLabels-1
- // Input parameter eng specifies the data and smoothness parts of the energy
- // after this constructor you need to call setNeighbors() to specify the neighborhood system
- MRF(int nPixels, int nLabels, EnergyFunction *eng);
- virtual ~MRF() { }
-
- // Returns true if energy function has been specified, returns false otherwise
- // By default, it always returns true. Can be modified by the supplier of
- // optimization algorithm
- virtual int isValid(){return true;};
-
- // *********** EVALUATING THE ENERGY
- typedef int Label;
- typedef double EnergyVal; /* The total energy of a labeling */
- typedef double CostVal; /* costs of individual terms of the energy */
-
- EnergyVal totalEnergy(); /* returns energy of current labeling */
- virtual EnergyVal dataEnergy() = 0; /* returns the data part of the energy */
- virtual EnergyVal smoothnessEnergy() = 0; /* returns the smoothness part of the energy */
- //Functional representation for data costs
- typedef CostVal (*DataCostFn)(int pix, Label l);
- // Functional representation for the general cost function type
- typedef CostVal (*SmoothCostGeneralFn)(int pix1, int pix2, Label l1, Label l2);
- // For general smoothness functions, some implementations try to cache all function values in an array
- // for efficiency. To prevent this, call the following function before calling initialize():
- void dontCacheSmoothnessCosts() {m_allocateArrayForSmoothnessCostFn = false;}
- // Use this function only for non-grid graphs. Sets pix1 and pix2 to be neighbors
- // with the specified weight. Can be called ONLY once for each pair of pixels
- // That is if pixel1 and pixel2 are neihbors, call either setNeighbors(pixel1,pixel2,weight)
- // or setNeighbors(pixel2,pixel1,weight), but NOT BOTH
- virtual void setNeighbors(int pix1, int pix2, CostVal weight)= 0;
- void initialize();
- // Runs optimization for nIterations. Input parameter time returns the time it took to
- // perform nIterations of optimization
- void optimize(int nIterations, float& time);
- virtual void optimizeAlg(int nIterations)=0;
- // *********** ACCESS TO SOLUTION
- // Returns pointer to array of size nPixels. Client may then read/write solution (but not deallocate array).
- virtual Label* getAnswerPtr()= 0;
- // returns the label of the input pixel
- virtual Label getLabel(int pixel)= 0;
- // sets label of a pixel
- virtual void setLabel(int pixel,Label label)= 0;
- // sets all the labels to zero
- virtual void clearAnswer() = 0;
- // use this function to pass any parameters to optimization algorithm.
- // The first argument is the number of passed, parameters and
- // the second argument is the pointer to the array of parameters
- virtual void setParameters(int numParam, void *param) = 0;
- // This function returns lower bound computed by the algorithm (if any)
- // By default, it returns 0.
- virtual double lowerBound(){return((double) 0);};
- // Returns 0 if the energy is not suitable for current optimization algorithm
- // Returns 1 if the energy is suitable for current optimization algorithm
- // Returns 2 if current optimizaiton algorithm does not check the energy
- virtual char checkEnergy();
- typedef enum
- {
- FUNCTION,
- ARRAY,
- THREE_PARAM,
- NONE
- } InputType;
- protected:
- int m_width, m_height; // width and height of a grid,if graph is a grid
- int m_nPixels; // number of pixels, for both grid and non-grid graphs
- int m_nLabels; // number of labels, for both grid and non-grid graphs
- bool m_grid_graph; // true if the graph is a 2D grid
- bool m_varWeights; // true if weights are spatially varying. To be used only with 2D grids
- bool m_initialized; // true if array m_V is allocated memory.
- EnergyFunction *m_e;
-
- InputType m_dataType;
- InputType m_smoothType;
- // *********** SET THE DATA COSTS
- // Following 2 functions set the data costs
- virtual void setData(DataCostFn dcost)=0;
- virtual void setData(CostVal* data)=0;
- // *********** SET THE SMOOTHNESS COSTS
- // following 3 functions set the smoothness costs
- // there are 2 ways to represent the smoothness costs, one with array, one with function
- // In addition, for 2D grid graphs spacially varying weights can be specified by 2 arrays
- // Smoothness cost depends on labels V(l1,l2) for all edges (except for a multiplier - see setCues() ).
- // V must be symmetric: V(l1,l2) = V(l2,l1)
- // V must be an array of size nLabels*nLabels. It is NOT copied into internal memory
- virtual void setSmoothness(CostVal* V)=0;
-
- // General smoothness cost can be specified by passing pointer to a function
- virtual void setSmoothness(SmoothCostGeneralFn cost)=0;
- // To prevent implementations from caching all general smoothness costs values, the flag below
- // can be set to false by calling dontCacheSmoothnessCosts() before calling initialize():
- bool m_allocateArrayForSmoothnessCostFn;
- // Use if the smoothness is V(l1,l2) = lambda * min ( |l1-l2|^m_smoothExp, m_smoothMax )
- // Can also add optional spatially varying weights for 2D grid graphs using setCues()
- virtual void setSmoothness(int smoothExp,CostVal smoothMax, CostVal lambda)=0;
- // You are not required to call setCues, in which case there is no multiplier.
- // Function below cannot be called for general cost function.
- // This function can be only used for a 2D grid graph
- // hCue and vCue must be arrays of size width*height in row major order.
- // They are NOT copied into internal memory.
- // hCue(x,y) holds the variable weight for edge between pixels (x+1,y) and (x,y)
- // vCue(x,y) holds the variable weight for edge between pixels (x,y+1) and (x,y)
- virtual void setCues(CostVal* hCue, CostVal* vCue)=0;
-
- virtual void initializeAlg()=0; // called by initialize()
- void commonInitialization(EnergyFunction *e);
- void checkArray(CostVal *V);
- };
- // *********** This class is for data costs
- // Data costs can be specified eithe by an array or by a pointer to a function
- // If specified by an array, use constructor DataCost(cost) where
- // cost is the array of type CostVal. The cost of pixel p and label l is
- // stored at cost[p*nLabels+l] where nLabels is the number of labels
- // If data costs are to be specified by a function, pass
- // a pointer to a function
- // CostVal costFn(int pix, Label lab)
- // which returns the
- // data cost of pixel pix to be assigned label lab
- class DataCost
- {
- friend class MRF;
- public:
- typedef MRF::CostVal CostVal;
- typedef MRF::DataCostFn DataCostFn;
- DataCost(CostVal *cost){m_costArray = cost;m_type = MRF::ARRAY; };
- DataCost(DataCostFn costFn){m_costFn = costFn;m_type = MRF::FUNCTION;};
- private:
- MRF::CostVal *m_costArray;
- MRF::DataCostFn m_costFn;
- MRF::InputType m_type;
- };
- // ***************** This class represents smoothness costs
- // If the smoothness is V(l1,l2) = lambda * min ( |l1-l2|^m_smoothExp, m_smoothMax )
- // use constructor SmoothnessCost(smoothExp,smoothMax,lambda)
- // If, in addition, there are spacially varying weights use constructor
- // SmoothnessCost(smoothExp,smoothMax,lambda,hWeights,vWeights)
- // hWeights and vWeights can be only used for a 2D grid graph
- // hWeights and vWeights must be arrays of size width*height in row major order.
- // They are NOT copied into internal memory.
- // hWeights(x,y) holds the variable weight for edge between pixels (x+1,y) and (x,y)
- // vWeights(x,y) holds the variable weight for edge between pixels (x,y+1) and (x,y)
- // If the smoothness costs are specified by input array V of type CostVal and
- // size nLabels*nLabels, use consructor SmoothnessCost(V).
- // If in addition, there are
- // are spacially varying weights use constructor SmoothnessCost(V,hWeights,vWeights)
- // Note that array V must be of size nLabels*nLabels, and be symmetric.
- // That is V[i*nLabels+j] = V[j*nLabels+i]
- // Finally, if the smoothness term is specified by a general function, use
- // constructor SmoothnessCost(costFn)
- class SmoothnessCost
- {
- friend class MRF;
- public:
- typedef MRF::CostVal CostVal;
- // Can be used for 2D grids and for general graphs
- // In case if used for 2D grids, the smoothness term WILL NOT be spacially varying
- SmoothnessCost(int smoothExp,CostVal smoothMax,CostVal lambda)
- {m_type=MRF::THREE_PARAM;m_smoothMax = smoothMax;m_smoothExp = smoothExp;m_lambda=lambda;m_varWeights=false;};
- // Can be used only for 2D grids
- // the smoothness term WILL BE be spacially varying
- SmoothnessCost(int smoothExp,CostVal smoothMax,CostVal lambda,CostVal *hWeights, CostVal *vWeights)
- {m_type=MRF::THREE_PARAM;m_smoothMax = smoothMax;m_smoothExp = smoothExp;m_lambda=lambda;
- m_varWeights = true;m_hWeights = hWeights; m_vWeights = vWeights;};
-
- // Can be used 2D grids and for general graphs
- // In case if used for 2D grids, the smoothness term WILL NOT be spacially varying
- SmoothnessCost(CostVal *V){m_V = V;m_type = MRF::ARRAY;m_varWeights=false;};
- // Can be used only for 2D grids
- // the smoothness term WILL BE be spacially varying
- SmoothnessCost(CostVal *V,CostVal *hWeights, CostVal *vWeights )
- {m_V = V;m_hWeights = hWeights; m_vWeights = vWeights; m_varWeights = true; m_type=MRF::ARRAY;};
- // Can be used 2D grids and for general graphs
- SmoothnessCost(MRF::SmoothCostGeneralFn costFn){m_costFn = costFn;m_type = MRF::FUNCTION;m_varWeights=false;};
- private:
- CostVal *m_V,*m_hWeights, *m_vWeights;
- MRF::SmoothCostGeneralFn m_costFn;
- MRF::InputType m_type;
- int m_smoothExp;
- CostVal m_smoothMax,m_lambda;
- bool m_varWeights;
- EnergyFunction *m_eng;
- };
- class EnergyFunction
- {
- public:
- EnergyFunction(DataCost *dataCost,SmoothnessCost *smoothCost)
- {m_dataCost = dataCost;m_smoothCost = smoothCost;};
- DataCost *m_dataCost;
- SmoothnessCost *m_smoothCost;
- };
- }
- #endif /* __MRF_H__ */
- /*
- virtual EnergyVal dataEnergy() = 0;
- virtual EnergyVal smoothnessEnergy() = 0;
- virtual void setNeighbors(int pix1, int pix2, CostVal weight)= 0;
- virtual void optimizeAlg(int nIterations)=0;
- virtual Label* getAnswerPtr()= 0;
- virtual Label getLabel(int pixel)= 0;
- virtual void setLabel(int pixel,Label label)= 0;
- virtual void clearAnswer() = 0;
- virtual void setParameters(int numParam, void *param) = 0;
- virtual void setData(DataCostFn dcost)=0;
- virtual void setData(CostVal* data)=0;
- virtual void setSmoothness(CostVal* V)=0;
- virtual void setSmoothness(SmoothCostGeneralFn cost)=0;
- virtual void setCues(CostVal* hCue, CostVal* vCue)=0;
- virtual void setSmoothness(int smoothExp,CostVal smoothMax, CostVal lambda);
- virtual EnergyVal lowerBound(){return((EnergyVal) 0);};
- */
|