Basic Image AlgorithmS Library 2.8.0

ExampleTriangleMesh.cpp

00001 /*
00002 This file is part of the BIAS library (Basic ImageAlgorithmS).
00003 
00004 Copyright (C) 2003-2009    (see file CONTACT for details)
00005   Multimediale Systeme der Informationsverarbeitung
00006   Institut fuer Informatik
00007   Christian-Albrechts-Universitaet Kiel
00008 
00009 
00010 BIAS is free software; you can redistribute it and/or modify
00011 it under the terms of the GNU Lesser General Public License as published by
00012 the Free Software Foundation; either version 2.1 of the License, or
00013 (at your option) any later version.
00014 
00015 BIAS is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU Lesser General Public License for more details.
00019 
00020 You should have received a copy of the GNU Lesser General Public License
00021 along with BIAS; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 */
00024 
00025 /** @example ExampleTriangleMesh.cpp
00026  *  @relates ThreeDOut,TriangleMesh
00027     @ingroup g_examples
00028     @brief Example for TriangleMesh object, writes a wrl with an image using level of detail
00029     @author MIP */
00030 
00031 #include <Utils/TriangleMesh.hh>
00032 #include <Utils/ThreeDOut.hh>
00033 #include <Base/Image/ImageIO.hh>
00034 #include <Filter/Rescale.hh>
00035 #include <Base/Common/FileHandling.hh>
00036 #include <Image/Camera.hh>
00037 #include <sstream>
00038 
00039 #include <iostream>
00040 
00041 using namespace std;
00042 using namespace BIAS;
00043 
00044 //#define TILE_MODE
00045 #define TILE_WIDTH 129
00046 #define TILE_HEIGHT 129
00047 
00048 void usage(char* name)
00049 {
00050   cout<<"usage:\n";
00051   cout<<name<<" <depthmap> <projection> <texture> [minCornerAngleDEG] [outputFile] [LevelOfDetail]\n";
00052   cout<<endl<<endl;
00053   cout<<"minCornerAngleDEG: discard triangle which contain a smaller angle"
00054       <<endl;
00055   cout<<"LevelOfDetail: 1:vertex for each pixel of full resolution, 2:"
00056       <<" of half resolution"<<endl;
00057 }
00058 
00059 int main(int argc, char* argv[])
00060 {
00061   bool TileMode = true;
00062   if(argc<3) {
00063     usage(argv[0]);
00064     return -1;
00065   }
00066 
00067   Camera<unsigned char> texture;
00068   if(ImageIO::Load(argv[3], texture)!=0) {
00069     cout<<"texture could not be loaded!\n";
00070     usage(argv[0]);
00071     return -1;
00072   }
00073   texture.ParseMetaData();
00074   Camera<float> depthMap;
00075   if(ImageIO::Load(argv[1], depthMap)!=0) {
00076     cout<<"depth map could not be loaded!\n";
00077     usage(argv[0]);
00078     if (string(argv[1])==string("UNITSPHERE")) {
00079       depthMap.Init(texture.GetWidth(), texture.GetHeight(), 1);
00080       depthMap.FillImageWithConstValue(1.0f);
00081     }
00082     else return -1;
00083   }
00084   depthMap.ParseMetaData();
00085 
00086   Projection P;
00087   if (P.Load(argv[2])!=0) {
00088     if (texture.IsProjValid()) {
00089       P = texture.GetProj();
00090     } else if (depthMap.IsProjValid()) {
00091       P = depthMap.GetProj();
00092     } else {
00093       cout<<"Projection could not be loaded from file or meta data!\n";
00094       usage(argv[0]);
00095       return -1;
00096     }
00097   }
00098 
00099   cout<<"meshing..."; cout.flush();
00100   double minCornerAngle = 3.0*M_PI/180.0;
00101   double maxViewingAngle = 91.0 * M_PI / 180.0;
00102   if(argc>4) {
00103     minCornerAngle = atof(argv[4])*M_PI/180.0;
00104   }
00105   cout<<"minCornerAngle = "<<minCornerAngle<<endl;
00106   TriangleMesh mesh(minCornerAngle, maxViewingAngle);
00107 
00108   double LevelOfDetail = -1.0;
00109   if(argc>6) {
00110     LevelOfDetail = atof(argv[6]);
00111   }
00112   if (LevelOfDetail>=0.0) TileMode = false;
00113   else TileMode = true;
00114 
00115   cout<<"Level of detail is "<< LevelOfDetail<<endl;
00116   if (fabs(LevelOfDetail)!=1.0) {
00117     //double maxlevel = log(double(depthMap.GetWidth()))/log(2.0)-6;
00118     //cout<<"maximum level is "<<maxlevel<<endl;
00119 
00120     for (double curLevel = 1.0;
00121          curLevel<fabs(LevelOfDetail); curLevel += 1.0) {
00122       Gauss<float, float> DepthSmooth;
00123       DepthSmooth.SetSigma(sqrt(1.0*1.0 - 0.5*0.5));
00124       Image<float> copyOfDepth = depthMap;
00125       DepthSmooth.Filter7x7GreyIgnoreBelowThreshold(depthMap, copyOfDepth,
00126                                                     0.0f);
00127       depthMap.Release();
00128       depthMap.Init(copyOfDepth.GetWidth()/2, copyOfDepth.GetHeight()/2);
00129       for (unsigned int y=0; y<depthMap.GetHeight(); y++) {
00130         for (unsigned int x=0; x<depthMap.GetWidth(); x++) {
00131           depthMap.GetImageDataArray()[y][x] =
00132             copyOfDepth.GetImageDataArray()[2*y][2*x];
00133         }
00134       }
00135       P.Rescale(2.0);
00136       //ImageIO::Save("depth"+FileHandling::toString(curLevel), depthMap);
00137       ImageIO::Save("depth"+FileHandling::toString(curLevel), depthMap);
00138     }
00139 
00140   }
00141 
00142   string vrmlfilename = "DenseTriangleMesh.wrl";
00143   if(argc>5) vrmlfilename = argv[5];
00144   ThreeDOut vrmlOut;
00145   if (!TileMode) {
00146 
00147     mesh.GenerateSimplifiedMesh(depthMap, P, texture, 0, 0,
00148                                 depthMap.GetWidth(),
00149                                 depthMap.GetHeight(), 0.7, 3.0);
00150     cout<<"finished\n"<<flush;
00151 
00152     vrmlOut.AddTriangleMesh(mesh, "mesh_from_"+string(argv[1]),
00153                             argv[3], true);
00154     cout<<"Writing VRML to "<<vrmlfilename<<flush<<endl;
00155     vrmlOut.VRMLOut(vrmlfilename);
00156     cout<<"finished\n";
00157   } else {
00158 
00159     // tile here into small image blocks, allows for writing of huge files
00160     ofstream vrmlfile(vrmlfilename.c_str());
00161     vrmlOut.VRMLOutWriteHeader(vrmlfile);
00162 
00163     unsigned int width, height;
00164     P.GetParameters()->GetImageSize(width, height);
00165     unsigned int tileWidth, tileHeight;
00166     bool xFinished = false;
00167     bool yFinished = false;
00168     //  bool finished = false;
00169     unsigned int xStart, yStart;
00170     unsigned int tileNum = 0;
00171     yStart = 0;
00172     int numTiles = (height/(TILE_HEIGHT-1)+1)*(width/(TILE_WIDTH-1)+1);
00173     cout<<"Writing "<< numTiles
00174         <<" tiles: "<<flush;
00175     while(!yFinished) {
00176       if(yStart+TILE_HEIGHT >= height) {
00177         yFinished = true;
00178         tileHeight = height-yStart;
00179       }
00180       else tileHeight = TILE_HEIGHT;
00181 
00182       cout<< double(tileNum)/double(numTiles)*100.0<<"% "<<flush;
00183       xFinished = false;
00184       xStart = 0;
00185       while(!xFinished) {
00186         stringstream ss;
00187         ss<<"mesh_from_"<<string(argv[1])<<"_t"<<tileNum;
00188         tileNum++;
00189         if(xStart+TILE_WIDTH >= width) {
00190           xFinished = true;
00191           tileWidth = width -xStart;
00192         }
00193         else
00194           tileWidth = TILE_WIDTH;
00195 
00196         if(mesh.GenerateDenseMesh(depthMap, P, texture,
00197                                   xStart, yStart, tileWidth, tileHeight)==0) {
00198           vrmlOut.AddTriangleMesh(mesh, ss.str(),
00199                                   argv[3], false);
00200           vrmlOut.VRMLOutIndexedFaceSets(vrmlfile);
00201           vrmlOut.RemoveAll();
00202         }
00203         xStart+=(tileWidth-1);
00204       }
00205       yStart+=(tileHeight-1);
00206     }
00207     cout<< "  finished."<<endl<<flush;
00208   }
00209 
00210   return 0;
00211 }
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends