G Fanelli论文中随机森林的头部姿态估计

时间:2015-04-17 08:01:12

标签: c++ opencv kinect

我一直在研究深度数据的头部姿势估计。我读过G Fanelli的论文 - "来自消费者深度相机的实时头部姿势估计" "随机回归森林的实时头部姿势估计"。我测试了数据和Fanelli在网站上发布的代码(http://www.vision.ee.ethz.ch/~gfanelli/head_pose/head_forest.html)。但是,当我运行代码时,有一个问题。 错误信息是"用法:./ head_pose_estimation config_file depth_image" 。我认为这是关于文件阅读,但我不知道如何解决它。

,代码是这样的:

int main(int argc, char* argv[])
{
    if( argc != 3 )
    {
        cout << "usage: ./head_pose_estimation config_file depth_image" << endl;
        exit(-1);
    }

    loadConfig(argv[1]);
    CRForestEstimator estimator;
    if( !estimator.loadForest(g_treepath.c_str(), g_ntrees) ){

        cerr << "could not read forest!" << endl;
        exit(-1);
    }

    string depth_fname(argv[2]);

    //read calibration file (should be in the same directory as the depth image!)
    string cal_filename = depth_fname.substr(0,depth_fname.find_last_of("/")+1);
    cal_filename += "depth.cal";
    ifstream is(cal_filename.c_str());
    if (!is){
        cerr << "depth.cal file not found in the same folder as the depth image! " << endl;
        return -1;
    }
    //read intrinsics only
    float depth_intrinsic[9];   for(int i =0; i<9; ++i) is >> depth_intrinsic[i];
    is.close();

    Mat depthImg;
    //read depth image (compressed!)
    if (!loadDepthImageCompressed( depthImg, depth_fname.c_str() ))
        return -1;

    Mat img3D;
    img3D.create( depthImg.rows, depthImg.cols, CV_32FC3 );

    //get 3D from depth
    for(int y = 0; y < img3D.rows; y++)
    {
        Vec3f* img3Di = img3D.ptr<Vec3f>(y);
        const int16_t* depthImgi = depthImg.ptr<int16_t>(y);

        for(int x = 0; x < img3D.cols; x++){

            float d = (float)depthImgi[x];

            if ( d < g_max_z && d > 0 ){

                img3Di[x][0] = d * (float(x) - depth_intrinsic[2])/depth_intrinsic[0];
                img3Di[x][1] = d * (float(y) - depth_intrinsic[5])/depth_intrinsic[4];
                img3Di[x][2] = d;
            }
            else{

                img3Di[x] = 0;
            }
        }
    }

    g_means.clear();
    g_votes.clear();
    g_clusters.clear();

    string pose_filename(depth_fname.substr(0,depth_fname.find_last_of('_')));
    pose_filename += "_pose.bin";

    cv::Vec<float,POSE_SIZE> gt;
    bool have_gt = false;
    //try to read in the ground truth from a binary file
    FILE* pFile = fopen(pose_filename.c_str(), "rb");
    if(pFile){

        have_gt = true;
        have_gt &= ( fread( &gt[0], sizeof(float),POSE_SIZE, pFile) == POSE_SIZE );
        fclose(pFile);
    }

    //do the actual estimate
    estimator.estimate(     img3D,
                            g_means,
                            g_clusters,
                            g_votes,
                            g_stride,
                            g_maxv,
                            g_prob_th,
                            g_larger_radius_ratio,
                            g_smaller_radius_ratio,
                            false,
                            g_th
                        );

    cout << "Heads found : " << g_means.size() << endl;

    //assuming there's only one head in the image!
    if(g_means.size()>0){

        cout << "Estimated: " << g_means[0][0] << " " << g_means[0][1] << " " << g_means[0][2] << " " << g_means[0][3] << " " << g_means[0][4] << " " << g_means[0][5] <<endl;

        float pt2d_est[2];
        float pt2d_gt[2];

        if(have_gt){
            cout << "Ground T.: " << gt[0] << " " << gt[1] << " " << gt[2] << " " << gt[3] << " " << gt[4] << " " << gt[5] <<endl;

            cv::Vec<float,POSE_SIZE> err = (gt-g_means[0]);
            //multiply(err,err,err);
            for(int n=0;n<POSE_SIZE;++n)
                err[n] = err[n]*err[n];

            float h_err = sqrt(err[0]+err[1]+err[2]);
            float a_err = sqrt(err[3]+err[4]+err[5]);

            cout << "Head error : " << h_err << " mm " << endl;
            cout << "Angle error : " << a_err <<" degrees " <<  endl;

            pt2d_gt[0] = depth_intrinsic[0]*gt[0]/gt[2] + depth_intrinsic[2];
            pt2d_gt[1] = depth_intrinsic[4]*gt[1]/gt[2] + depth_intrinsic[5];
        }

        pt2d_est[0] = depth_intrinsic[0]*g_means[0][0]/g_means[0][2] + depth_intrinsic[2];
        pt2d_est[1] = depth_intrinsic[4]*g_means[0][1]/g_means[0][2] + depth_intrinsic[5];
    }

    return 0;
}

任何人都可以告诉我如何解决这个问题吗?非常感谢!

1 个答案:

答案 0 :(得分:1)

在测试应用程序之前,您应该始终阅读readme.txt(此处附在head_pose_estimation.tgz中):

  

要运行示例代码,请键入./head_pose_estimation config.txt data/frame_XXXX_depth.binconfig.txt文件包含所有参数   头部姿势估计所需的,例如,到森林的路径,   stride和z阈值用于分割人员   背景