Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

InterestPointListIO.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Geometry_InterestPointListIO_h
00002 #define Impala_Core_Geometry_InterestPointListIO_h
00003 
00004 #include "Core/Geometry/InterestPointList.h"
00005 #include "Core/Geometry/InterestCircle.h"
00006 #include "Core/Geometry/InterestRectangleZ.h"
00007 #include "Core/Vector/VectorTem.h"
00008 
00009 #include <iostream>
00010 #include <fstream>
00011 
00012 namespace Impala
00013 {
00014 namespace Sandbox
00015 {
00016 namespace Koen
00017 {
00018 
00019 using namespace Impala::Core::Geometry;
00020 
00021 
00022 void
00023 WriteRegionsToStreamFormatKoen(std::ostream& fs, InterestPointList& outputPointList, bool writeDescriptors, int borderOffset)
00024 {
00025     ILOG_VAR(Sandbox.koen.WriteRegionsToStreamFormatKoen);
00026     /* Format KOEN version 1.0
00027        -----------------------
00028        First line:  KOEN1 (format version)
00029        Second line: Descriptor dimensionality count (0 if only interest items)
00030        Third line:  Number of interest items
00031     */
00032     int dimensionCount = -1;
00033     fs << "KOEN1\n";
00034     if(writeDescriptors)
00035     {
00036         if(outputPointList.size() == 0)
00037         {
00038             dimensionCount = 0;
00039         }
00040         else
00041         {
00042             dimensionCount = (*(outputPointList.begin()))->mDescriptor.size();
00043         }
00044         fs << dimensionCount << "\n";
00045     }
00046     else
00047     {
00048         fs << "0\n";
00049     }
00050     fs << outputPointList.size() << "\n";
00051     for(InterestPointList::iterator iter = outputPointList.begin(); iter != outputPointList.end(); iter++)
00052     {
00053         InterestPoint* point = *iter;
00054         // shift by 1 for consistency with the public file format (which uses 1..n instead of 0..n-1)
00055         // make coordinates equal to the original image, without the borders removed
00056         fs << point->Serialize(borderOffset+1, borderOffset+1);
00057         if(writeDescriptors)
00058         {
00059             if(point->mDescriptor.size() != dimensionCount)
00060             {
00061                 ILOG_ERROR("Your code has created descriptors with variable length!");
00062                 throw "Dimension mismatch!";
00063             }
00064             for(int i = 0; i < dimensionCount; i++)
00065             {
00066                 fs << " " << point->mDescriptor[i];
00067             }
00068         }
00069         fs << ";\n";
00070     }
00071 }
00072 
00073 
00074 void
00075 WriteRegionsToBuffer(Util::IOBuffer* buffer, InterestPointList& outputPointList, bool writeDescriptors, int borderOffset)
00076 {
00077     ILOG_VAR(Sandbox.koen.WriteRegionsToBuffer);
00078     /* Format BINDESC1
00079        -----------------------
00080        First 8 bytes: BINDESC1
00081        Second 8 bytes: data type (CIRCLE is typical)
00082        Next 16 bytes: 4 integers:
00083                         elementsPerPoint = values[0]
00084                         dimensionCount = values[1]
00085                         pointCount = values[2]
00086                         bytesPerElement = values[3]
00087     */
00088     int elementsPerPoint = 0;
00089     int dimensionCount = 0;
00090     int pointCount = outputPointList.size();
00091     int bytesPerElement = 8;
00092 
00093     String magic = "BINDESC1";
00094     String dataType = "UNKNOWN ";
00095     String geometry = "";
00096     if(outputPointList.size() > 0)
00097     {
00098         Core::Vector::VectorTem<Real64>* p = (*(outputPointList.begin()))->PointAsVector(borderOffset+1, borderOffset+1);
00099         elementsPerPoint = p->Size();
00100         delete p;
00101 
00102         dimensionCount = (*(outputPointList.begin()))->mDescriptor.size();
00103         geometry = (*(outputPointList.begin()))->geometryType();
00104         if(geometry == "CircleZ")
00105         {
00106             dataType = "CIRCLE  ";
00107         } 
00108         else if(geometry == "RectangleZ")
00109         {
00110             dataType = "RECT    ";
00111         }
00112     }
00113     if(!writeDescriptors) dimensionCount = 0;
00114     
00115     ILOG_DEBUG("Writing header...");
00116     buffer->Write(magic.c_str(), 8);
00117     buffer->Write(dataType.c_str(), 8);
00118     buffer->Write(&elementsPerPoint, 4);
00119     buffer->Write(&dimensionCount, 4);
00120     buffer->Write(&pointCount, 4);
00121     buffer->Write(&bytesPerElement, 4);
00122     ILOG_DEBUG("Wrote full header");
00123 
00124     for(InterestPointList::iterator iter = outputPointList.begin(); iter != outputPointList.end(); iter++)
00125     {
00126         InterestPoint* point = *iter;
00127         // shift by 1 for consistency with the public file format (which uses 1..n instead of 0..n-1)
00128         // make coordinates equal to the original image, without the borders removed
00129         Core::Vector::VectorTem<Real64>* p = point->PointAsVector(borderOffset+1, borderOffset+1);
00130         if(p->Size() != elementsPerPoint)
00131         {
00132             ILOG_ERROR("Point representations do not have equal length!");
00133             return;
00134         }
00135         buffer->Write(p->GetData(), sizeof(Real64) * elementsPerPoint);
00136         delete p;
00137     }
00138 
00139     if(dimensionCount == 0) return;
00140     
00141     Core::Vector::VectorTem<Real64> v = Core::Vector::VectorTem<Real64>(dimensionCount);
00142     for(InterestPointList::iterator iter = outputPointList.begin(); iter != outputPointList.end(); iter++)
00143     {
00144         InterestPoint* point = *iter;
00145         if(point->mDescriptor.size() != dimensionCount)
00146         {
00147             ILOG_ERROR("Your code has created descriptors with variable length!");
00148         }
00149         for(int i = 0; i < dimensionCount; i++)
00150         {
00151             v[i] = point->mDescriptor[i];
00152         }
00153         buffer->Write(v.GetData(), sizeof(Real64) * dimensionCount);
00154     }
00155 }
00156 
00157 
00158 void
00159 WritePointListToFile(String filename, InterestPointList& outputPointList, bool writeDescriptors, int borderOffset, String format, bool appendToExisting=false)
00160 {
00161     if((format == "bindesc1") || (format == "binary"))
00162     {
00163         Util::IOBuffer* buffer = new Util::IOBufferFile(filename, false, false);
00164         WriteRegionsToBuffer(buffer, outputPointList, writeDescriptors, borderOffset);
00165         delete buffer;
00166     }
00167     else
00168     {
00169         std::ios::openmode flags = std::ios::ate | std::ios::out | std::ios::in;
00170         if(!appendToExisting)
00171         {
00172             flags = std::ios::out;
00173         }
00174         std::ofstream fs(filename.c_str(), flags);
00175         WriteRegionsToStreamFormatKoen(fs, outputPointList, writeDescriptors, borderOffset);
00176         fs.close();
00177     }
00178 }
00179 
00180 
00181 void
00182 ReadRegionsFromStreamFormatKoen(CString content, InterestPointList& outputPointList, bool readDescriptors, int borderOffset)
00183 {
00184     ILOG_VAR(Sandbox.koen.ReadRegionsFromStreamFormatKoen);
00185     //note: this function will probably not work on Windows due to line ending problems
00186 
00187     /* Format KOEN version 1.0
00188        -----------------------
00189        First line:  KOEN1 (format version)
00190        Second line: Descriptor dimensionality count (0 if only interest items)
00191        Third line:  Number of interest items
00192     */
00193 
00194     Util::StringParser sp(content);
00195     //std::cout << content << "x" << fileSize << std::endl;
00196 
00197     // first line: KOEN1
00198     String header = sp.GetString('\n');
00199     if(header != String("KOEN1"))
00200     {
00201         ILOG_ERROR("Unsupported region format: " << header);
00202         return;
00203     }
00204 
00205     // second line: dimensionality
00206     int dimensionCount = sp.GetInt('\n');
00207     int regionCount = sp.GetInt('\n');
00208     ILOG_DEBUG("Reading file; dimensionCount = " << dimensionCount << "; regionCount = " << regionCount);
00209     for(int i = 0; i < regionCount; i++)
00210     {
00211         InterestPoint* point = 0;
00212 
00213         String line = sp.GetString('\n');
00214         Util::StringParser sp2(line);
00215         String region = sp2.GetString(';');
00216         if(region.substr(0, 8) == "<CIRCLE ")
00217         {
00218             // shift by 1 for consistency with the public file format (which uses 1..n instead of 0..n-1)
00219             // make coordinates equal to the original image, without the borders removed
00220             point = new InterestCircle(region, borderOffset+1, borderOffset+1);
00221         }
00222         else
00223         {
00224             ILOG_ERROR("Unsupported region: " << region);
00225             throw "Unsupported serialization type!";
00226         }
00227 
00228         if(readDescriptors)
00229         {
00230             String descriptor = sp2.GetString(';');
00231             Util::StringParser sp3(descriptor);
00232             if(dimensionCount > 0)
00233             {
00234                 point->mDescriptor.reserve(dimensionCount);
00235                 for(int j = 0; j < dimensionCount; j++)
00236                 {
00237                     point->mDescriptor.push_back(sp3.GetDouble());
00238                 }
00239             }
00240         }
00241         if(point)
00242         {
00243             outputPointList.push_back(point);
00244         }
00245     }
00246 }
00247 
00248 
00249 void
00250 ReadRegionsFromStreamFormatKoen(std::istream& fs, InterestPointList& outputPointList, bool readDescriptors, int borderOffset)
00251 {
00252     ILOG_VAR(Sandbox.koen.ReadRegionsFromStreamFormatKoen);
00253     //note: this function will probably not work on Windows due to line ending problems
00254 
00255     fs.seekg(0, std::ios_base::end);
00256     int fileSize = fs.tellg();
00257     fs.seekg(0, std::ios_base::beg);
00258     char* buffer = new char[fileSize];
00259     // 0 character should never be read from a file, so we should get the whole file
00260     fs.get(buffer, fileSize, '\0');
00261 
00262     String content(buffer);
00263     ReadRegionsFromStreamFormatKoen(content, outputPointList, readDescriptors, borderOffset);
00264 }
00265 
00266 
00267 void
00268 ReadPointListFromBuffer(Util::IOBuffer* buffer, 
00269                         InterestPointList& pointList, 
00270                         bool readDescriptors, int borderOffset)
00271 {
00272     ILOG_VAR(Sandbox.koen.ReadRegionsFromBuffer);
00273     /* Format BINDESC1
00274        -----------------------
00275        First 8 bytes: BINDESC1
00276        Second 8 bytes: data type (CIRCLE is typical)
00277        Next 16 bytes: 4 integers:
00278                         elementsPerPoint = values[0]
00279                         dimensionCount = values[1]
00280                         pointCount = values[2]
00281                         bytesPerElement = values[3]
00282     */
00283     int elementsPerPoint = 0;
00284     int dimensionCount = 0;
00285     int pointCount = 0;
00286     int bytesPerElement = 8;
00287 
00288     String magic = "BINDESC1";
00289     String dataType = "UNKNOWN ";
00290     String geometry = "";
00291     
00292     char buf[9];
00293     for (int i=0 ; i<9 ; i++)
00294         buf[i] = 0;
00295     
00296     ILOG_DEBUG("Reading header...");
00297     // read magic
00298     buffer->Read(buf, 8);
00299     if(String(buf) != magic)
00300     {
00301         ILOG_ERROR("ReadPointListFromBuffer invalid magic");
00302         return;
00303     }
00304     
00305     // read dataType
00306     buffer->Read(buf, 8);
00307     dataType = String(buf);
00308     if(dataType == "CIRCLE  ")
00309     {
00310         geometry = "CircleZ";
00311     } 
00312     else if(dataType == "RECT    ")
00313     {
00314         geometry = "RectangleZ";
00315     }
00316 
00317     buffer->Read(&elementsPerPoint, 4);
00318     buffer->Read(&dimensionCount, 4);
00319     buffer->Read(&pointCount, 4);
00320     buffer->Read(&bytesPerElement, 4);
00321     ILOG_DEBUG("Read full header");
00322     if(bytesPerElement != 8)
00323     {
00324         ILOG_ERROR("Can only read BINDESC1 with 8 bytes per element (double)");
00325         return;
00326     }
00327 
00328     // read the points
00329     Core::Vector::VectorTem<Real64> pointVector = 
00330         Core::Vector::VectorTem<Real64>(elementsPerPoint);
00331     for(int i = 0; i < pointCount; i++)
00332     {
00333         buffer->Read(pointVector.GetData(), sizeof(Real64) * elementsPerPoint);
00334         if(geometry == "CircleZ")
00335         {
00336             InterestCircle* point = 
00337                 new InterestCircle(pointVector, borderOffset+1, borderOffset+1);
00338             pointList.push_back(point);
00339         }
00340         else if(geometry == "RectangleZ")
00341         {
00342             ILOG_ERROR("Cannot deserialize rectangles: code not written");
00343             //InterestRectangleZ* point = 
00344             //    new InterestRectangleZ(pointVector, borderOffset+1,
00345             //                           borderOffset+1);
00346             //pointList.push_back(point);
00347         }
00348     }
00349 
00350     if(dimensionCount == 0) return;
00351     if(!readDescriptors) return;
00352     
00353     Core::Vector::VectorTem<Real64> v = 
00354         Core::Vector::VectorTem<Real64>(dimensionCount);
00355     for(InterestPointList::iterator iter = pointList.begin(); iter != pointList.end(); iter++)
00356     {
00357         InterestPoint* point = *iter;
00358         buffer->Read(v.GetData(), sizeof(Real64) * dimensionCount);
00359         point->mDescriptor.reserve(dimensionCount);
00360         for(int i = 0; i < dimensionCount; i++)
00361         {
00362             point->mDescriptor.push_back(v[i]);
00363         }
00364     }
00365 }
00366 
00367 
00368 void
00369 ReadPointListFromFile(String filename, InterestPointList& outputPointList,
00370                       bool readDescriptors, int borderOffset)
00371 {
00372     Util::IOBuffer* buffer = new Util::IOBufferFile(filename, true, false);
00373     char buf[9];
00374     for (int i=0 ; i<9 ; i++)
00375         buf[i] = 0;
00376     buffer->Read(buf, 8);
00377     
00378     if(String(buf) == "BINDESC1")
00379     {
00380         // Format BINDESC1
00381         buffer->Seek(0, SEEK_SET);
00382         ReadPointListFromBuffer(buffer, outputPointList, readDescriptors, 
00383                                 borderOffset);
00384         delete buffer;
00385     }
00386     else
00387     {
00388         delete buffer;
00389         
00390         // Format KOEN1
00391         std::ifstream fs(filename.c_str());
00392         ReadRegionsFromStreamFormatKoen
00393             (fs, outputPointList, false, borderOffset);
00394         fs.close();
00395     }
00396 }
00397 
00398 
00399 } // namespace Koen
00400 } // namespace Sandbox
00401 } // namespace Impala
00402 
00403 #endif

Generated on Fri Mar 19 09:31:09 2010 for ImpalaSrc by  doxygen 1.5.1