simple_dense_inference.py
int main( int argc, char* argv[]){
if (argc<4){
printf("Usage: %s image annotations output\n", argv[0] );
return 1;
}
// Number of labels
const int M = 21;
// Load the color image and some crude(粗糙的) annotations (which are used in a simple classifier)
int W, H, GW, GH;
// W和H是图片的宽和高
// GW, GH是标注的宽和高
// read the origion image im
unsigned char * im = readPPM( argv[1], W, H );
if (!im){
printf("Failed to load image!\n");
return 1;
}
// read the annotated image anno
unsigned char * anno = readPPM( argv[2], GW, GH );
if (!anno){
printf("Failed to load annotations!\n");
return 1;
}
if (W!=GW || H!=GH){
printf("Annotation size doesn't match image!\n");
return 1;
}
// get the unary
/// Put your own unary classifier here! ///
float * unary = classify( anno, W, H, M );
///
// Setup the CRF model
// W,H,W是图像的宽,高和类别数
DenseCRF2D crf(W, H, M);
// Specify the unary potential as an array of size W*H*(#classes)
// packing order: x0y0l0 x0y0l1 x0y0l2 .. x1y0l0 x1y0l1 ... (row-order)
crf.setUnaryEnergy( unary );
// add a color independent term (feature = pixel location 0..W-1, 0..H-1)
// x_stddev = 3
// y_stddev = 3
// weight = 3
// stddev是标准偏差
crf.addPairwiseGaussian( 3, 3, 3 );
// add a color dependent term (feature = xyrgb)
// x_stddev = 60
// y_stddev = 60
// r_stddev = g_stddev = b_stddev = 20
// weight = 10
// 计算$/sum k_{smoothness kernel}(fi; fj)*Q_i$然后pairwise_.push_back( potential );
crf.addPairwiseBilateral( 60, 60, 20, 20, 20, im, 10 );
// 计算$/sum k_{appearance kernel}(fi; fj)*Q_i$然后pairwise_.push_back( potential );
// Do map inference
short * map = new short[W*H];
// short是整型,是result
crf.map(10, map);
// Store the result
unsigned char *res = colorize( map, W, H );
writePPM( argv[3], W, H, res );
delete[] im;
delete[] anno;
delete[] res;
delete[] map;
delete[] unary;
}
其中有几个关键的函数,分别是
DenseCRF2D crf(W, H, M);
crf.setUnaryEnergy( unary )
crf.addPairwiseGaussian( 3, 3, 3 )
crf.addPairwiseBilateral( 60, 60, 20, 20, 20, im, 10 );
crf.map(10, map)
DenseCRF::DenseCRF(int N, int M)
DenseCRF::DenseCRF(int N, int M) : N_(N), M_(M) {
unary_ = allocate( N_*M_ );
// allocate貌似是内存分配用的,一共有M_个类别
additional_unary_ = allocate( N_*M_ );
current_ = allocate( N_*M_ );// stepInference时当前的Q(标签值)
next_ = allocate( N_*M_ ); // stepInference时下次迭代的Q(标签值)
tmp_ = allocate( 2*N_*M_ );// tmp是compatiblilty function given by Potts model
// Set the additional_unary_ to zero
memset( additional_unary_, 0, sizeof(float)*N_*M_ );
// memset将某一块内存中的内容全部设置为指定的值
}
void DenseCRF::setUnaryEnergy
void DenseCRF::setUnaryEnergy(const float* unary) {
memcpy( unary_, unary, N_*M_*sizeof(float) );
// memcpy内存拷贝函数,把unary拷贝到unary_中
}
void DenseCRF2D::addPairwiseGaussian
void DenseCRF2D::addPairwiseGaussian ( float sx, float sy, float w, const SemiMetricFunction * function ) {
// add a color indepe