Middlebury是每个研究立体匹配算法的人不可能不使用的网站,Middlebury提供了许多标准的测试库,这极大地推进了立体匹配算法的进展。Middlebury提供的标准库,其计算出的视差保存在后缀名为.pfm的文件中,Middlebury本身也提供了读取.pfm文件中C++源码和Matlab源码。尽管如此,将源码写成与OpenCV结合的形式是我们更期望的,以下我写的读写.pfm文件的源码。相对于Middlebury给定的源码,更简洁易懂。
#include "CCC/COMCV.h" #include <fstream> void writPFM(Mat_<float> &disp, float &scale, string path) { ofstream out(path, ios_base::binary); out << "Pf" << endl << disp.cols << " " << disp.rows << endl << scale << endl; ; i >= ; i--)//因为存储是从最后行开始存储的 ; j < disp.cols; j++) out.write((const char*)(&disp(i, j)), sizeof(float)); out.close(); } void readPFM(Mat_<float> &disp, float &scale, string path) { ifstream in(path, ios_base::binary); int cols; int rows; ]; , '\n'); in.get();//文件头 , ' '); in.get(); cols = atoi(tmp);//列数 , '\n'); in.get(); rows = atoi(tmp); //行数 , '\n'); in.get(); scale = atof(tmp);//缩放因子 disp.create(rows, cols); ; i >= ; i--)//因为存储是从最后行开始存储的 ; j < disp.cols; j++) in.read((char*)(&disp(i, j)), sizeof(float)); in.close(); } void calcXYZ(Mat_<float> &disp, float f, float cx, float cy, float doffs, float baseline, Mat_<Vec3f> xyz) { ; i < disp.rows; i++) ; j < disp.cols; j++) { float x = baseline*(j - cx) / (disp(i, j) + doffs); float y = baseline*(i - cy) / (disp(i, j) + doffs); float z = baseline*f / (disp(i, j) + doffs); xyz(i, j) = Vec3f(x, y, z); } } void writPLY(Mat_<Vec3f> &xyz, Mat_<Vec3b> &img,string path) { ofstream out(path); out << "ply"; out << endl << "format ascii 1.0"; out << endl << "element vertex " << xyz.total(); out << endl << "property float32 x"; out << endl << "property float32 y"; out << endl << "property float32 z"; out << endl << "property uchar red"; out << endl << "property uchar green"; out << endl << "property uchar blue"; out << endl << "end_header"; ; i < xyz.rows; i++) ; j < xyz.cols; j++) ] << ] << ] << " " << (int)img(i, j)[2] << " " << (int)img(i, j)[1] << " " << (int)img(i,j)[0]; out.close(); } void PFM2XML(string pfmpath, string xmlpath) { Mat_<float> pfm; float scale; readPFM(pfm, scale, pfmpath); saveXML(xmlpath, pfm); writPFM(pfm, scale, pfmpath + "_verify.pfm"); } void PFM2PLY(string pfmpath, string calibpath, string imgpath, string plypath) { Mat_<float> pfm; float scale; readPFM(pfm, scale, pfmpath); ifstream in(calibpath); string cxstr, cystr, fstr, doffsstr, baselinestr, tmp; in >> fstr >> tmp >> cxstr >> tmp >> tmp >> cystr >> tmp >> tmp >> tmp; in >> tmp >> tmp >> tmp >> tmp >> tmp >> tmp >> tmp >> tmp >> tmp; in >> doffsstr >> baselinestr; in.close(); //cout << endl << fstr << endl << cxstr << endl << cystr << endl << doffsstr << endl << baselinestr; ).c_str()); , cxstr.length() - ).c_str()); , cystr.length() - ).c_str()); ).c_str()); ).c_str()); //cout << endl << f << endl << cx << endl << cy << endl << doffs << endl << baseline;getchar(); Mat_<Vec3f> xyz(pfm.rows, pfm.cols); calcXYZ(pfm, f, cx, cy, doffs, baseline, xyz); Mat_<Vec3b> img = imread(imgpath,1); writPLY(xyz, img, plypath); } void PFM2XM2LPLY_DIR() { string dir = "./../TestData"; vector<string> dirs = cv_GetListFolders(dir); ; k < dirs.size(); k++) { string pfmpath = dirs[k] + "/disp0GT.pfm"; string xmlpath = dirs[k] + "/disp0GT.xml"; string calibpath = dirs[k] + "/calib.txt"; string imgpath = dirs[k] + "/im0.png"; string plypath = dirs[k] + "/0xyz.ply"; PFM2XML(pfmpath, xmlpath); PFM2PLY(pfmpath, calibpath, imgpath, plypath); } }