int main(int args, char ** argv) {
    misc::process_args(args, argv);
    load_image(file_name[0], left_pyramid[0].rgb, left_pyramid[0].H, left_pyramid[0].W);
    load_image(file_name[1], right_pyramid[0].rgb, right_pyramid[0].H, right_pyramid[0].W);
    if (left_pyramid[0].H != right_pyramid[0].H || left_pyramid[0].W != right_pyramid[0].W) {
        printf("The size of two pictures differ!! quit....");
        return 0;
    }
    if (left_pyramid[0].H >= MAX_HEIGHT || right_pyramid[0].W >= MAX_WIDTH) {
        printf("Input : %d x %d, program : %d %d\n", left_pyramid[0].H, left[0].W, MAX_HEIGHT, MAX_WIDTH);
        puts("Image too big. change settings.hpp and re-compile.");
        return 0;
    }

timer.reset();
    if (use_lab) {
      left_pyramid[0].computeLab();
      right_pyramid[0].computeLab();
    }
    for (int i = 0; i + 1 < levels; ++i) {
      left_pyramid[i+1].shrinkPicture(left_pyramid[i+1].rgb, left_pyramid[i].rgb, left_pyramid[i].H, left_pyramid[i].W);
      right_pyramid[i+1].shrinkPicture(right_pyramid[i+1].rgb, right_pyramid[i].rgb, right_pyramid[i].H, right_pyramid[i].W);
      if (use_lab) {
        left_pyramid[i+1].shrinkPicture(left_pyramid[i+1].lab, left_pyramid[i].lab, left_pyramid[i].H, left_pyramid[i].W);
        right_pyramid[i+1].shrinkPicture(right_pyramid[i+1].lab, right_pyramid[i].lab, right_pyramid[i].H, right_pyramid[i].W);
      }
    }

    for (int lvl = levels - 1; lvl >= 0; -- lvl) {
        int idx = lvl % OBJ_NUM;
        left[idx].init(left_pyramid[lvl]);
        right[idx].init(right_pyramid[lvl]);
        if (lvl == levels - 1) {
            left[idx].noPrediction(max_disparity / (1 << lvl));
        } else {
            DP::getSupportProb(left[idx].rgb, right[idx].rgb, 
                                left[idx].H, left[idx].W, max_disparity / (1 << lvl));
            DP::getProbMatrix(lvl, max_disparity / (1 << (lvl + 1)), max_disparity / (1 << lvl), dataset);
            DP::getInterval(pixel_intv_threshold * (1 << lvl)/*, tot_threshold*/);
            left[idx].readPrediction(left[(lvl + 1)%OBJ_NUM].disparity);
            // left[idx].intersectInterval(left[(lvl + 1) % OBJ_NUM]);
        } 
        // Now use the INTERVAL to find the new disparities.
        left_pyramid[lvl].computeGradient();
        right_pyramid[lvl].computeGradient();
        left[idx].buildForest(tree_intv_threshold, use_lab);
        left[idx].noPrediction(max_disparity / (1 << lvl));
        left[idx].initDisparity();
        updateTable(255 * 0.1);
        left[idx].stereoMatch(right[idx], 1, use_lab);
        misc::median_filter(left[idx].disparity, left[idx].H, left[idx].W, 3);
        // save_image(layername[lvl][0], left[idx].disparity, left[idx].H, left[idx].W, scale * (1 << lvl));
    } // end of layer iteration.

timer.check("all");

    save_image(file_name[2], left[0].disparity, left[0].H, left[0].W, scale);

    return 0;
}
int main(int args, char ** argv) {
    misc::process_args(args, argv);
    load_image(file_name[0], left_layer.rgb, left_layer.H, left_layer.W);
    load_image(file_name[1], right_layer.rgb, right_layer.H, right_layer.W);
  timer.reset();
    left.init(left_layer); right.init(right_layer);

    //misc::median_filter_rgb(left.rgb, left.H, left.W, 1);
    //misc::median_filter_rgb(right.rgb, right.H, right.W, 1);
    if (use_lab) {
      left_layer.computeLab();
      // misc::median_filter_rgb(left.lab, left.H, left.W, 1);
    }
    left.buildTree(use_lab);	
    left_layer.computeGradient();
    right_layer.computeGradient();
    // next part : compute disparity
    left.initDisparity();
    updateTable(255 * 0.1);
// timer.check("build forest");
    left.stereoMatch(right, 1, max_disparity, use_lab);    
    misc::median_filter(left.disparity, left.H, left.W); //TODO: why radius = 2, not 3 as dp

timer.check("all");
	//save
    save_image(file_name[2], left.disparity, left.H, left.W, scale);
    //save_image(file_name[3], right.disparity, right.H, right.W, scale);
    return 0;
}