00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __VCGLIB_IMPORTERBUNDLER
00024 #define __VCGLIB_IMPORTERBUNDLER
00025
00026 #include <stddef.h>
00027 #include <stdio.h>
00028 #include <vcg/complex/complex.h>
00029
00030 #include <vcg/complex/algorithms/update/bounding.h>
00031 #include <wrap/callback.h>
00032 #include <wrap/io_trimesh/io_mask.h>
00033 #include <QImageReader>
00034
00035 extern "C"
00036 {
00037 #include <jhead.h>
00038 int ReadJpegSections (FILE * infile, ReadMode_t ReadMode);
00039 void ResetJpgfile(void);
00040 }
00041
00042 namespace vcg {
00043 namespace tri {
00044 namespace io {
00045
00046 struct Correspondence{
00047 Correspondence(unsigned int id_img_,unsigned int key_,float x_,float y_):id_img(id_img_),key(key_),x(x_),y(y_){}
00048 unsigned int id_img,key;
00049 float x;
00050 float y;
00051 };
00052
00053 typedef std::vector<Correspondence> CorrVec;
00054
00058 template <class OpenMeshType>
00059 class ImporterOUT
00060 {
00061 public:
00062
00063 typedef typename OpenMeshType::VertexPointer VertexPointer;
00064 typedef typename OpenMeshType::ScalarType ScalarType;
00065 typedef typename OpenMeshType::CoordType CoordType;
00066 typedef typename OpenMeshType::VertexType VertexType;
00067 typedef typename OpenMeshType::FaceType FaceType;
00068 typedef typename OpenMeshType::VertexIterator VertexIterator;
00069 typedef typename OpenMeshType::FaceIterator FaceIterator;
00070 typedef typename OpenMeshType::EdgeIterator EdgeIterator;
00071
00072 static void readline(FILE *fp, char *line, int max=100){
00073 fgets ( line, max, fp);
00074 }
00075
00076 static bool ReadHeader(FILE *fp,unsigned int &num_cams, unsigned int &num_points){
00077 char line[100];
00078 readline(fp, line);
00079 if( line[0]=='\0' ) return false;
00080 line[18]='\0';
00081 if(0!=strcmp("# Bundle file v0.3", line)) return false;
00082 readline(fp, line);
00083 if(line[0]=='\0') return false;
00084 sscanf(line, "%d %d", &num_cams, &num_points);
00085 return true;
00086 }
00087
00088 static bool ReadHeader(const char * filename,unsigned int &, unsigned int &){
00089 FILE *fp = fopen(filename, "r");
00090 if(!fp) return false;
00091 ReadHeader(fp);
00092 fclose(fp);
00093 return true;
00094 }
00095
00096
00097 static int Open( OpenMeshType &m, std::vector<Shot<ScalarType> > & shots,
00098 std::vector<std::string > & image_filenames,
00099 const char * filename,const char * filename_images, CallBackPos *cb=0)
00100 {
00101 unsigned int num_cams,num_points;
00102 typedef typename vcg::Matrix44<ScalarType> Matrix44x;
00103 typedef typename vcg::Matrix33<ScalarType> Matrix33x;
00104 FILE *fp = fopen(filename,"r");
00105 if(!fp) return false;
00106 ReadHeader(fp, num_cams, num_points);
00107 char line[100];
00108 if(cb) cb(0,"Reading images");
00109 ReadImagesFilenames(filename_images, image_filenames);
00110 const QString path_im = QFileInfo(filename_images).absolutePath()+QString("/");
00111
00112 if(cb) cb(50,"Reading cameras");
00113 shots.resize(num_cams);
00114 for(uint i = 0; i < num_cams;++i)
00115 {
00116 float f, k1, k2;
00117 float R[16]={0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1};
00118 vcg::Point3f t;
00119
00120 readline(fp, line); if(line[0]=='\0') return false; sscanf(line, "%f %f %f", &f, &k1, &k2);
00121
00122 readline(fp, line); if(line[0]=='\0') return false; sscanf(line, "%f %f %f", &(R[0]), &(R[1]), &(R[2])); R[3] = 0;
00123 readline(fp, line); if(line[0]=='\0') return false; sscanf(line, "%f %f %f", &(R[4]), &(R[5]), &(R[6])); R[7] = 0;
00124 readline(fp, line); if(line[0]=='\0') return false; sscanf(line, "%f %f %f", &(R[8]), &(R[9]), &(R[10])); R[11] = 0;
00125
00126 readline(fp, line); if(line[0]=='\0') return false; sscanf(line, "%f %f %f", &(t[0]), &(t[1]), &(t[2]));
00127
00128 Matrix44x mat = Matrix44x::Construct(Matrix44f(R));
00129
00130 Matrix33x Rt = Matrix33x( Matrix44x(mat), 3);
00131 Rt.Transpose();
00132
00133 CoordType pos = Rt * CoordType(t[0], t[1], t[2]);
00134
00135 shots[i].Extrinsics.SetTra(CoordType(-pos[0],-pos[1],-pos[2]));
00136 shots[i].Extrinsics.SetRot(mat);
00137
00138 shots[i].Intrinsics.FocalMm = f;
00139 shots[i].Intrinsics.k[0] = 0.0;
00140 shots[i].Intrinsics.k[1] = 0.0;
00141 shots[i].Intrinsics.PixelSizeMm = vcg::Point2<ScalarType>(1,1);
00142 QSize size;
00143 QImageReader sizeImg(QString::fromStdString(image_filenames[i]));
00144 if(sizeImg.size()==QSize(-1,-1))
00145 {
00146 QImageReader sizeImg(QString::fromStdString(qPrintable(path_im)+image_filenames[i]));
00147 size=sizeImg.size();
00148 }
00149 else
00150 size=sizeImg.size();
00151 shots[i].Intrinsics.ViewportPx = vcg::Point2i(size.width(),size.height());
00152 shots[i].Intrinsics.CenterPx[0] = (int)((double)shots[i].Intrinsics.ViewportPx[0]/2.0f);
00153 shots[i].Intrinsics.CenterPx[1] = (int)((double)shots[i].Intrinsics.ViewportPx[1]/2.0f);
00154
00155 }
00156
00157
00158 typename OpenMeshType::template PerVertexAttributeHandle<CorrVec> ch = vcg::tri::Allocator<OpenMeshType>::template GetPerVertexAttribute<CorrVec>(m,"correspondences");
00159
00160 typename OpenMeshType::VertexIterator vi = vcg::tri::Allocator<OpenMeshType>::AddVertices(m,num_points);
00161 for(uint i = 0; i < num_points;++i,++vi){
00162 double x,y,z;
00163 unsigned int r,g,b,i_cam, key_sift,n_corr;
00164 fscanf(fp,"%lf %lf %lf ",&x,&y,&z);
00165 (*vi).P() = vcg::Point3<typename OpenMeshType::ScalarType>(x,y,z);
00166 fscanf(fp,"%d %d %d ",&r,&g,&b);
00167 (*vi).C() = vcg::Color4b(r,g,b,255);
00168
00169 fscanf(fp,"%d ",&n_corr);
00170 for(uint j = 0; j < n_corr; ++j){
00171 fscanf(fp,"%d %d %lf %lf ",&i_cam,&key_sift,&x,&y);
00172 Correspondence corr(i_cam,key_sift,x,y);
00173 ch[i].push_back(corr);
00174 }
00175 }
00176 vcg::tri::UpdateBounding<OpenMeshType>::Box(m);
00177 fclose(fp);
00178
00179 return (shots.size() == 0);
00180 }
00181
00182
00183 static bool ReadImagesFilenames(const char * filename,std::vector<std::string> &image_filenames)
00184 {
00185 FILE * fp = fopen(filename,"r");
00186 if (!fp) return false;
00187 else
00188 {
00189 char line[1000], name[1000];
00190 while(!feof(fp)){
00191 readline(fp, line, 1000);
00192 if(line[0] == '\0') continue;
00193 sscanf(line, "%s", name);
00194 std::string n(name);
00195 image_filenames.push_back(n);
00196 }
00197 }
00198 fclose(fp);
00199 return true;
00200 }
00201
00202 static bool AddIntrinsics(vcg::Shotf &shot, const char * image_file)
00203 {
00204 ::ResetJpgfile();
00205 FILE * pFile = fopen(image_file, "rb");
00206 int ret = ::ReadJpegSections (pFile, READ_METADATA);
00207 fclose(pFile);
00208 if(ret==0) return false;
00209 shot.Intrinsics.ViewportPx = vcg::Point2i(ImageInfo.Width, ImageInfo.Height);
00210 shot.Intrinsics.CenterPx = vcg::Point2f(float(ImageInfo.Width/2.0), float(ImageInfo.Height/2.0));
00211
00212 return true;
00213 }
00214 };
00215
00216
00217
00218 }
00219 }
00220 }
00221
00222 #endif
00223