From dd8c26474dfa3ee2cde2e4c39366fe9df41e667d Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 23 Sep 2020 13:07:03 +0200 Subject: [PATCH] vcg/wrap/import_out.h uses easyexif lib, small typo corrected in alnParser --- wrap/io_trimesh/alnParser.h | 26 +-- wrap/io_trimesh/import_out.h | 333 +++++++++++++++++++---------------- 2 files changed, 190 insertions(+), 169 deletions(-) diff --git a/wrap/io_trimesh/alnParser.h b/wrap/io_trimesh/alnParser.h index d01a6b4e7..1e7fd4a4f 100644 --- a/wrap/io_trimesh/alnParser.h +++ b/wrap/io_trimesh/alnParser.h @@ -30,14 +30,14 @@ struct RangeMap { - RangeMap() - { - quality = 1.0f; - } - - std::string filename; - Matrix44m trasformation; - float quality; + RangeMap() + { + quality = 1.0f; + } + + std::string filename; + Matrix44m transformation; + float quality; }; class ALNParser @@ -66,7 +66,7 @@ class ALNParser { (*rm).filename = (*it); (*rm).quality = 1.0f; - (*rm).trasformation.SetIdentity(); + (*rm).transformation.SetIdentity(); } files.clear(); return NoError; @@ -106,10 +106,10 @@ class ALNParser rm.quality = (float) atof(occurrence+2); assert(rm.quality>0); - fscanf(stream,"%f %f %f %f \n",&(rm.trasformation[0][0]),&(rm.trasformation[0][1]),&(rm.trasformation[0][2]),&(rm.trasformation[0][3])); - fscanf(stream,"%f %f %f %f \n",&(rm.trasformation[1][0]),&(rm.trasformation[1][1]),&(rm.trasformation[1][2]),&(rm.trasformation[1][3])); - fscanf(stream,"%f %f %f %f \n",&(rm.trasformation[2][0]),&(rm.trasformation[2][1]),&(rm.trasformation[2][2]),&(rm.trasformation[2][3])); - fscanf(stream,"%f %f %f %f \n",&(rm.trasformation[3][0]),&(rm.trasformation[3][1]),&(rm.trasformation[3][2]),&(rm.trasformation[3][3])); + fscanf(stream,"%f %f %f %f \n",&(rm.transformation[0][0]),&(rm.transformation[0][1]),&(rm.transformation[0][2]),&(rm.transformation[0][3])); + fscanf(stream,"%f %f %f %f \n",&(rm.transformation[1][0]),&(rm.transformation[1][1]),&(rm.transformation[1][2]),&(rm.transformation[1][3])); + fscanf(stream,"%f %f %f %f \n",&(rm.transformation[2][0]),&(rm.transformation[2][1]),&(rm.transformation[2][2]),&(rm.transformation[2][3])); + fscanf(stream,"%f %f %f %f \n",&(rm.transformation[3][0]),&(rm.transformation[3][1]),&(rm.transformation[3][2]),&(rm.transformation[3][3])); rangemaps.push_back(rm); } diff --git a/wrap/io_trimesh/import_out.h b/wrap/io_trimesh/import_out.h index f2435ae3e..0564dbcc7 100644 --- a/wrap/io_trimesh/import_out.h +++ b/wrap/io_trimesh/import_out.h @@ -31,26 +31,21 @@ #include #include #include - -extern "C" -{ -#include -int ReadJpegSections (FILE * infile, ReadMode_t ReadMode); -void ResetJpgfile(void); -} +#include +#include //external easyexif lib namespace vcg { namespace tri { namespace io { - struct Correspondence{ - Correspondence(unsigned int id_img_,unsigned int key_,float x_,float y_):id_img(id_img_),key(key_),x(x_),y(y_){} - unsigned int id_img,key; - float x; - float y; - }; +struct Correspondence{ + Correspondence(unsigned int id_img_,unsigned int key_,float x_,float y_):id_img(id_img_),key(key_),x(x_),y(y_){} + unsigned int id_img,key; + float x; + float y; +}; - typedef std::vector CorrVec; +typedef std::vector CorrVec; /** This class encapsulate a filter for opening bundler file @@ -59,148 +54,174 @@ template class ImporterOUT { public: - -typedef typename OpenMeshType::VertexPointer VertexPointer; -typedef typename OpenMeshType::ScalarType ScalarType; - typedef typename OpenMeshType::CoordType CoordType; -typedef typename OpenMeshType::VertexType VertexType; -typedef typename OpenMeshType::FaceType FaceType; -typedef typename OpenMeshType::VertexIterator VertexIterator; -typedef typename OpenMeshType::FaceIterator FaceIterator; -typedef typename OpenMeshType::EdgeIterator EdgeIterator; - -static void readline(FILE *fp, char *line, int max=100){ - fgets ( line, max, fp); -} - -static bool ReadHeader(FILE *fp,unsigned int &num_cams, unsigned int &num_points){ - char line[100]; - readline(fp, line); - if( line[0]=='\0' ) return false; - line[18]='\0'; - if(0!=strcmp("# Bundle file v0.3", line)) return false; - readline(fp, line); - if(line[0]=='\0') return false; - if (sscanf(line, "%d %d", &num_cams, &num_points) != 2) return false; - return true; -} - -static int Open( OpenMeshType &m, std::vector > & shots, - std::vector & image_filenames, - const char * filename,const char * filename_images, CallBackPos *cb=0) -{ - unsigned int num_cams,num_points; - typedef typename vcg::Matrix44 Matrix44x; - typedef typename vcg::Matrix33 Matrix33x; - FILE *fp = fopen(filename,"r"); - if(!fp) return false; - ReadHeader(fp, num_cams, num_points); - char line[100]; - if(cb) cb(0,"Reading images"); - ReadImagesFilenames(filename_images, image_filenames); - const QString path_im = QFileInfo(filename_images).absolutePath()+QString("/"); - - if(cb) cb(50,"Reading cameras"); - shots.resize(num_cams); - for(uint i = 0; i < num_cams;++i) - { - float f, k1, k2; - float R[16]={0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1}; - vcg::Point3f t; - - readline(fp, line); if(line[0]=='\0') return false; if (sscanf(line, "%f %f %f", &f, &k1, &k2) != 3) return false; - - readline(fp, line); if(line[0]=='\0') return false; if (sscanf(line, "%f %f %f", &(R[0]), &(R[1]), &(R[2])) != 3) return false; R[3] = 0; - readline(fp, line); if(line[0]=='\0') return false; if (sscanf(line, "%f %f %f", &(R[4]), &(R[5]), &(R[6])) != 3) return false; R[7] = 0; - readline(fp, line); if(line[0]=='\0') return false; if (sscanf(line, "%f %f %f", &(R[8]), &(R[9]), &(R[10])) != 3) return false; R[11] = 0; - readline(fp, line); if(line[0]=='\0') return false; if (sscanf(line, "%f %f %f", &(t[0]), &(t[1]), &(t[2])) != 3) return false; - - Matrix44x mat = Matrix44x::Construct(Matrix44f(R)); - - Matrix33x Rt = Matrix33x( Matrix44x(mat), 3); - Rt.Transpose(); - - CoordType pos = Rt * CoordType(t[0], t[1], t[2]); - - shots[i].Extrinsics.SetTra(CoordType(-pos[0],-pos[1],-pos[2])); - shots[i].Extrinsics.SetRot(mat); - - shots[i].Intrinsics.FocalMm = f; - shots[i].Intrinsics.k[0] = 0.0;//k1; To be uncommented when distortion is taken into account reliably - shots[i].Intrinsics.k[1] = 0.0;//k2; - shots[i].Intrinsics.PixelSizeMm = vcg::Point2(1,1); - QSize size; - QImageReader sizeImg(QString::fromStdString(image_filenames[i])); - if(sizeImg.size()==QSize(-1,-1)) - { - QImageReader sizeImg(QString::fromStdString(qPrintable(path_im)+image_filenames[i])); - size=sizeImg.size(); - } - else - size=sizeImg.size(); - shots[i].Intrinsics.ViewportPx = vcg::Point2i(size.width(),size.height()); - shots[i].Intrinsics.CenterPx[0] = (int)((double)shots[i].Intrinsics.ViewportPx[0]/2.0f); - shots[i].Intrinsics.CenterPx[1] = (int)((double)shots[i].Intrinsics.ViewportPx[1]/2.0f); - //AddIntrinsics(shots[i], std::string(filename_images_path).append(image_filenames[i]).c_str()); - } - - // load all correspondences - typename OpenMeshType::template PerVertexAttributeHandle ch = vcg::tri::Allocator::template GetPerVertexAttribute(m,"correspondences"); - - typename OpenMeshType::VertexIterator vi = vcg::tri::Allocator::AddVertices(m,num_points); - for(uint i = 0; i < num_points;++i,++vi){ - double x,y,z; - unsigned int r,g,b,i_cam, key_sift,n_corr; - if (fscanf(fp,"%lf %lf %lf ",&x,&y,&z) != 3) return false; - (*vi).P() = vcg::Point3(x,y,z); - if (fscanf(fp,"%d %d %d ",&r,&g,&b) != 3) return false; - (*vi).C() = vcg::Color4b(r,g,b,255); - - if (fscanf(fp,"%d ",&n_corr) != 1) return false; - for(uint j = 0; j < n_corr; ++j){ - if (fscanf(fp,"%d %d %lf %lf ",&i_cam,&key_sift,&x,&y) != 4) return false; - Correspondence corr(i_cam,key_sift,x,y); - ch[i].push_back(corr); - } - } - vcg::tri::UpdateBounding::Box(m); - fclose(fp); - - return (shots.size() == 0); -} - - -static bool ReadImagesFilenames(const char * filename,std::vector &image_filenames) -{ - FILE * fp = fopen(filename,"r"); - if (!fp) return false; - else - { - char line[1000], name[1000]; - while(!feof(fp)){ - readline(fp, line, 1000); - if(line[0] == '\0') continue; //ignore empty lines (in theory, might happen only at end of file) - if (sscanf(line, "%s", name) != 1) return false; - std::string n(name); - image_filenames.push_back(n); - } - } - fclose(fp); - return true; -} - -static bool AddIntrinsics(vcg::Shotf &shot, const char * image_file) -{ - ::ResetJpgfile(); - FILE * pFile = fopen(image_file, "rb"); - int ret = ::ReadJpegSections (pFile, READ_METADATA); - fclose(pFile); - if(ret==0) return false; - shot.Intrinsics.ViewportPx = vcg::Point2i(ImageInfo.Width, ImageInfo.Height); - shot.Intrinsics.CenterPx = vcg::Point2f(float(ImageInfo.Width/2.0), float(ImageInfo.Height/2.0)); - - return true; -} + + typedef typename OpenMeshType::VertexPointer VertexPointer; + typedef typename OpenMeshType::ScalarType ScalarType; + typedef typename OpenMeshType::CoordType CoordType; + typedef typename OpenMeshType::VertexType VertexType; + typedef typename OpenMeshType::FaceType FaceType; + typedef typename OpenMeshType::VertexIterator VertexIterator; + typedef typename OpenMeshType::FaceIterator FaceIterator; + typedef typename OpenMeshType::EdgeIterator EdgeIterator; + + static void readline(FILE *fp, char *line, int max=100){ + fgets ( line, max, fp); + } + + static bool ReadHeader(FILE *fp,unsigned int &num_cams, unsigned int &num_points){ + char line[100]; + readline(fp, line); + if( line[0]=='\0' ) return false; + line[18]='\0'; + if(0!=strcmp("# Bundle file v0.3", line)) return false; + readline(fp, line); + if(line[0]=='\0') return false; + if (sscanf(line, "%d %d", &num_cams, &num_points) != 2) return false; + return true; + } + + static int Open( + OpenMeshType &m, + std::vector > & shots, + std::vector & image_filenames, + const char * filename, + const char * filename_images, + CallBackPos *cb=0) + { + unsigned int num_cams,num_points; + typedef typename vcg::Matrix44 Matrix44x; + typedef typename vcg::Matrix33 Matrix33x; + FILE *fp = fopen(filename,"r"); + if(!fp) return false; + ReadHeader(fp, num_cams, num_points); + char line[100]; + if(cb) cb(0,"Reading images"); + ReadImagesFilenames(filename_images, image_filenames); + const QString path_im = QFileInfo(filename_images).absolutePath()+QString("/"); + + if(cb) cb(50,"Reading cameras"); + shots.resize(num_cams); + for(uint i = 0; i < num_cams;++i) + { + float f, k1, k2; + float R[16]={0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1}; + vcg::Point3f t; + + readline(fp, line); if(line[0]=='\0') return false; if (sscanf(line, "%f %f %f", &f, &k1, &k2) != 3) return false; + + readline(fp, line); if(line[0]=='\0') return false; if (sscanf(line, "%f %f %f", &(R[0]), &(R[1]), &(R[2])) != 3) return false; R[3] = 0; + readline(fp, line); if(line[0]=='\0') return false; if (sscanf(line, "%f %f %f", &(R[4]), &(R[5]), &(R[6])) != 3) return false; R[7] = 0; + readline(fp, line); if(line[0]=='\0') return false; if (sscanf(line, "%f %f %f", &(R[8]), &(R[9]), &(R[10])) != 3) return false; R[11] = 0; + readline(fp, line); if(line[0]=='\0') return false; if (sscanf(line, "%f %f %f", &(t[0]), &(t[1]), &(t[2])) != 3) return false; + + Matrix44x mat = Matrix44x::Construct(Matrix44f(R)); + + Matrix33x Rt = Matrix33x( Matrix44x(mat), 3); + Rt.Transpose(); + + CoordType pos = Rt * CoordType(t[0], t[1], t[2]); + + shots[i].Extrinsics.SetTra(CoordType(-pos[0],-pos[1],-pos[2])); + shots[i].Extrinsics.SetRot(mat); + + shots[i].Intrinsics.FocalMm = f; + shots[i].Intrinsics.k[0] = 0.0;//k1; To be uncommented when distortion is taken into account reliably + shots[i].Intrinsics.k[1] = 0.0;//k2; + shots[i].Intrinsics.PixelSizeMm = vcg::Point2(1,1); + QSize size; + QImageReader sizeImg(QString::fromStdString(image_filenames[i])); + if(sizeImg.size()==QSize(-1,-1)) + { + QImageReader sizeImg(QString::fromStdString(qPrintable(path_im)+image_filenames[i])); + size=sizeImg.size(); + } + else + size=sizeImg.size(); + shots[i].Intrinsics.ViewportPx = vcg::Point2i(size.width(),size.height()); + shots[i].Intrinsics.CenterPx[0] = (int)((double)shots[i].Intrinsics.ViewportPx[0]/2.0f); + shots[i].Intrinsics.CenterPx[1] = (int)((double)shots[i].Intrinsics.ViewportPx[1]/2.0f); + //AddIntrinsics(shots[i], std::string(filename_images_path).append(image_filenames[i]).c_str()); + } + + // load all correspondences + typename OpenMeshType::template PerVertexAttributeHandle ch = vcg::tri::Allocator::template GetPerVertexAttribute(m,"correspondences"); + + typename OpenMeshType::VertexIterator vi = vcg::tri::Allocator::AddVertices(m,num_points); + for(uint i = 0; i < num_points;++i,++vi){ + double x,y,z; + unsigned int r,g,b,i_cam, key_sift,n_corr; + if (fscanf(fp,"%lf %lf %lf ",&x,&y,&z) != 3) return false; + (*vi).P() = vcg::Point3(x,y,z); + if (fscanf(fp,"%d %d %d ",&r,&g,&b) != 3) return false; + (*vi).C() = vcg::Color4b(r,g,b,255); + + if (fscanf(fp,"%d ",&n_corr) != 1) return false; + for(uint j = 0; j < n_corr; ++j){ + if (fscanf(fp,"%d %d %lf %lf ",&i_cam,&key_sift,&x,&y) != 4) return false; + Correspondence corr(i_cam,key_sift,x,y); + ch[i].push_back(corr); + } + } + vcg::tri::UpdateBounding::Box(m); + fclose(fp); + + return (shots.size() == 0); + } + + + static bool ReadImagesFilenames(const char * filename,std::vector &image_filenames) + { + FILE * fp = fopen(filename,"r"); + if (!fp) return false; + else + { + char line[1000], name[1000]; + while(!feof(fp)){ + readline(fp, line, 1000); + if(line[0] == '\0') continue; //ignore empty lines (in theory, might happen only at end of file) + if (sscanf(line, "%s", name) != 1) return false; + std::string n(name); + image_filenames.push_back(n); + } + } + fclose(fp); + return true; + } + + static bool AddIntrinsics(vcg::Shotf &shot, const char * image_file) + { + // Read the JPEG file into a buffer + FILE *fp = fopen(qUtf8Printable(image_file), "rb"); + if (!fp) { + std::cerr << "Exif Parsing: Unable to open file:\n\"%1\"\n\nError details: file %1 is not readable."; + return false; + } + fseek(fp, 0, SEEK_END); + unsigned long fsize = ftell(fp); + rewind(fp); + unsigned char *buf = new unsigned char[fsize]; + if (fread(buf, 1, fsize, fp) != fsize) { + std::cerr << "Exif Parsing: Unable to read the content of the opened file:\n\"%1\"\n\nError details: file %1 is not readable."; + delete[] buf; + fclose(fp); + return false; + } + fclose(fp); + + // Parse EXIF + easyexif::EXIFInfo ImageInfo; + int ret = ImageInfo.parseFrom(buf, fsize); + delete[] buf; + if (ret == 0) { + std::cerr << "Warning unable to parse exif for file %s" << qPrintable(image_file); + return false; + } + + shot.Intrinsics.ViewportPx = vcg::Point2i(ImageInfo.ImageWidth, ImageInfo.ImageHeight); + shot.Intrinsics.CenterPx = vcg::Point2f(float(ImageInfo.ImageWidth/2.0), float(ImageInfo.ImageHeight/2.0)); + + return true; + } }; // end class