00001 #ifndef Impala_Core_Feature_PointDescriptorIO_h
00002 #define Impala_Core_Feature_PointDescriptorIO_h
00003
00004 #include "Core/Matrix/Mat.h"
00005 #include "Core/Matrix/MatFunc.h"
00006 #include "Util/StringParser.h"
00007
00008 #include <iostream>
00009 #include <fstream>
00010
00011 namespace Impala
00012 {
00013 namespace Core
00014 {
00015 namespace Feature
00016 {
00017
00018
00019 void
00020 WriteBINDESC1ToBuffer(Util::IOBuffer* buffer, Matrix::Mat* points, Matrix::Mat* descriptors, String theDataType)
00021 {
00022 ILOG_VAR(Core.Feature.PointDescriptorIO.WriteBINDESC1ToBuffer);
00023
00024 using namespace Impala::Core::Matrix;
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 int elementsPerPoint = MatNrCol(points);
00036 int dimensionCount = 0;
00037 int pointCount = MatNrRow(points);
00038 int bytesPerElement = 8;
00039
00040 if(descriptors)
00041 {
00042 if(MatNrRow(descriptors) > 0)
00043 {
00044 dimensionCount = MatNrCol(descriptors);
00045 if(MatNrRow(descriptors) != pointCount)
00046 {
00047 ILOG_ERROR("Dimension mismatch in points/descriptors: " <<
00048 pointCount << " " << MatNrRow(descriptors));
00049 }
00050 }
00051 }
00052
00053 String magic = "BINDESC1";
00054 String dataType = "UNKNOWN ";
00055 if(theDataType.size() == 8)
00056 {
00057 dataType = theDataType;
00058 }
00059 else
00060 {
00061 ILOG_ERROR("Coding error: your datatype specification should be 8 bytes long");
00062 }
00063
00064 ILOG_DEBUG("Writing header...");
00065 buffer->Write(magic.c_str(), 8);
00066 buffer->Write(dataType.c_str(), 8);
00067 buffer->Write(&elementsPerPoint, 4);
00068 buffer->Write(&dimensionCount, 4);
00069 buffer->Write(&pointCount, 4);
00070 buffer->Write(&bytesPerElement, 4);
00071 ILOG_DEBUG("Wrote full header");
00072
00073 for(int i = 0; i < pointCount; i++)
00074 {
00075 buffer->Write(MatE(points, i, 0), sizeof(Real64) * elementsPerPoint);
00076 }
00077
00078 if(dimensionCount == 0) return;
00079
00080 for(int i = 0; i < pointCount; i++)
00081 {
00082 buffer->Write(MatE(descriptors, i , 0), sizeof(Real64) * dimensionCount);
00083 }
00084 }
00085
00086
00087 void
00088 WriteKOEN1ToBuffer(Util::IOBuffer* buffer, Matrix::Mat* points, Matrix::Mat* descriptors, String theDataType)
00089 {
00090 ILOG_VAR(Core.Feature.PointDescriptorIO.WriteKOEN1ToBuffer);
00091
00092 using namespace Impala::Core::Matrix;
00093
00094
00095
00096
00097
00098
00099 buffer->Write("KOEN1\n", 6);
00100 int elementsPerPoint = MatNrCol(points);
00101 int dimensionCount = 0;
00102 int pointCount = MatNrRow(points);
00103 int bytesPerElement = 8;
00104
00105 if(descriptors)
00106 {
00107 if(MatNrRow(descriptors) > 0)
00108 {
00109 dimensionCount = MatNrCol(descriptors);
00110 if(MatNrRow(descriptors) != pointCount)
00111 {
00112 ILOG_ERROR("Dimension mismatch in points/descriptors: " <<
00113 pointCount << " " << MatNrRow(descriptors));
00114 }
00115 }
00116 }
00117
00118 String tmp = MakeString(dimensionCount) + "\n" + MakeString(pointCount) + "\n";
00119 buffer->Write(tmp.c_str(), tmp.size());
00120
00121 for(int i = 0; i < pointCount; i++)
00122 {
00123 String line = "<" + theDataType;
00124 for(int j = 0; j < elementsPerPoint; j++)
00125 {
00126 line += " " + MakeString(*MatE(points, i, j));
00127 }
00128 line += ">;";
00129 if(dimensionCount)
00130 {
00131 for(int j = 0; j < dimensionCount; j++)
00132 {
00133 line += " " + MakeString(*MatE(descriptors, i, j));
00134 }
00135 }
00136 line += ";\n";
00137
00138 buffer->Write(line.c_str(), line.size());
00139 }
00140 }
00141
00142
00143 String
00144 ReadBINDESC1FromBuffer(Matrix::Mat*& points, Matrix::Mat*& descriptors, Util::IOBuffer* buffer, bool readPoints, bool readDescriptors)
00145 {
00146 ILOG_VAR(Core.Feature.PointDescriptorIO.ReadBINDESC1FromBuffer);
00147
00148 using namespace Impala::Core::Matrix;
00149 char buf[9];
00150 for (int i=0 ; i<9 ; i++)
00151 buf[i] = 0;
00152 buffer->Read(buf, 8);
00153
00154 if(String(buf) == "BINDESC1")
00155 {
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 int elementsPerPoint = 0;
00167 int dimensionCount = 0;
00168 int pointCount = 0;
00169 int bytesPerElement = 8;
00170
00171 String dataType = "UNKNOWN ";
00172
00173 char buf[9];
00174 for (int i=0 ; i<9 ; i++)
00175 buf[i] = 0;
00176
00177 ILOG_DEBUG("Reading header...");
00178
00179
00180 buffer->Read(buf, 8);
00181 dataType = String(buf);
00182
00183 buffer->Read(&elementsPerPoint, 4);
00184 buffer->Read(&dimensionCount, 4);
00185 buffer->Read(&pointCount, 4);
00186 buffer->Read(&bytesPerElement, 4);
00187 ILOG_DEBUG("Read full header");
00188 if(bytesPerElement != 8)
00189 {
00190 ILOG_ERROR("Can only read BINDESC1 with 8 bytes per element (double)");
00191 return "";
00192 }
00193
00194 if(!readPoints)
00195 {
00196 buffer->Seek(elementsPerPoint * pointCount * bytesPerElement, SEEK_CUR);
00197 }
00198 else
00199 {
00200 points = MatCreate<Mat>(pointCount, elementsPerPoint);
00201 buffer->Read(points->mData, elementsPerPoint * pointCount * bytesPerElement);
00202 }
00203
00204 if(readDescriptors)
00205 {
00206 descriptors = MatCreate<Mat>(pointCount, dimensionCount);
00207 if(dimensionCount > 0)
00208 buffer->Read(descriptors->mData, dimensionCount * pointCount *
00209 bytesPerElement);
00210 }
00211
00212 return dataType;
00213 }
00214 else if(String(buf).substr(0, 5) == "KOEN1")
00215 {
00216
00217
00218
00219
00220
00221
00222 buffer->Seek(0, SEEK_SET);
00223
00224
00225 String header = buffer->ReadLine();
00226 if(header != String("KOEN1"))
00227 {
00228 ILOG_ERROR("Unsupported region format: " << header);
00229 return "";
00230 }
00231
00232
00233 int dimensionCount = Util::StringParser(buffer->ReadLine()).GetInt();
00234 int pointCount = Util::StringParser(buffer->ReadLine()).GetInt();
00235 ILOG_DEBUG("Reading file; dimensionCount = " << dimensionCount << "; pointCount = " << pointCount);
00236 if(readPoints)
00237 points = MatCreate<Mat>(pointCount, 5);
00238 if(readDescriptors)
00239 descriptors = MatCreate<Mat>(pointCount, dimensionCount);
00240
00241 for(int i = 0; i < pointCount; i++)
00242 {
00243 String line = buffer->ReadLine();
00244 Util::StringParser sp2(line);
00245 String region = sp2.GetString(';');
00246 if(readPoints)
00247 {
00248 if(region.substr(0, 8) == "<CIRCLE ")
00249 {
00250 Util::StringParser sp(region);
00251 String temp = sp.GetString(' ');
00252 *MatE(points, i, 0) = sp.GetDouble(' ');
00253 *MatE(points, i, 1) = sp.GetDouble(' ');
00254 *MatE(points, i, 2) = sp.GetDouble(' ');
00255 *MatE(points, i, 3) = sp.GetDouble(' ');
00256 *MatE(points, i, 4) = sp.GetDouble('>');
00257 }
00258 else
00259 {
00260 ILOG_ERROR("Unsupported region: " << region);
00261 throw "Unsupported serialization type!";
00262 }
00263 }
00264
00265 if(readDescriptors)
00266 {
00267 String descriptor = sp2.GetString(';');
00268 Util::StringParser sp3(descriptor);
00269 if(dimensionCount > 0)
00270 {
00271 for(int j = 0; j < dimensionCount; j++)
00272 {
00273 *MatE(descriptors, i, j) = sp3.GetDouble();
00274 }
00275 }
00276 }
00277 }
00278 return "CIRCLE";
00279 }
00280 else
00281 {
00282 ILOG_ERROR("Unknown format to read point descriptors from: " << String(buf));
00283 return "ERROR";
00284 }
00285 }
00286
00287
00288 }
00289 }
00290 }
00291
00292 #endif