Go to the documentation of this file.00001
00063 #include <cob_3d_mapping_common/io.h>
00064 #include <cob_3d_mapping_common/label_defines.h>
00065
00066 #include <iostream>
00067 #include <fstream>
00068 #include <math.h>
00069
00070 using namespace std;
00071
00072 int cob_3d_mapping_common::PPMReader::mapLabels(const string &file_name,
00073 pcl::PointCloud<pcl::PointXYZRGB> &cloud,
00074 bool remove_undef_points)
00075 {
00076 ifstream ppmFile;
00077 ppmFile.open(file_name.c_str());
00078 if(!ppmFile.is_open())
00079 {
00080 cout << "Could not open \"" << file_name << "\"" << endl;
00081 return (-1);
00082 }
00083
00084 try
00085 {
00086 size_t width, height;
00087 size_t word = 0;
00088 char c;
00089 string value("");
00090
00091
00092 while (word < 4)
00093 {
00094 c = ppmFile.get();
00095 if (!isspace(c))
00096 {
00097 if (c == '#')
00098 {
00099 cout << "Comment: ";
00100 getline(ppmFile, value);
00101 cout << value << endl;
00102 value = "";
00103 }
00104 else
00105 value += c;
00106 }
00107 else
00108 {
00109 word++;
00110 if (word == 2) width = atoi(value.c_str());
00111 else if(word == 3) height = atoi(value.c_str());
00112 value = "";
00113 }
00114 }
00115
00116
00117 if (width != cloud.width || height != cloud.height)
00118 {
00119 cout << "Size of PPM file ("
00120 << width << " x " << height
00121 << ") does not match the size of point cloud ("
00122 << cloud.width << " x " << cloud.height << ")" << endl;
00123 ppmFile.close();
00124 return(-1);
00125 }
00126
00127
00128 word = 0;
00129 size_t point = 0;
00130 uint8_t col[3];
00131 uint32_t rgb;
00132 while (!ppmFile.eof())
00133 {
00134 value.clear();
00135 ppmFile >> value;
00136 col[word] = atoi(value.c_str());
00137 word++;
00138 if (word == 3)
00139 {
00140 rgb = ((uint32_t)col[0] << 16 | (uint32_t)col[1] << 8 | (uint32_t) col[2]);
00141 if (rgb != LBL_PLANE && rgb != LBL_EDGE && rgb != LBL_COR && rgb != LBL_CYL && rgb != LBL_SPH)
00142 {
00143 cloud.points[point].r = (LBL_UNDEF >> 16) & 0x0000ff;
00144 cloud.points[point].g = (LBL_UNDEF >> 8) & 0x0000ff;
00145 cloud.points[point].b = (LBL_UNDEF) & 0x0000ff;
00146 if (remove_undef_points)
00147 {
00148 cloud.points[point].x = std::numeric_limits<float>::quiet_NaN();
00149 cloud.points[point].y = std::numeric_limits<float>::quiet_NaN();
00150 cloud.points[point].z = std::numeric_limits<float>::quiet_NaN();
00151 }
00152 }
00153 else
00154 {
00155 cloud.points[point].r = col[0];
00156 cloud.points[point].g = col[1];
00157 cloud.points[point].b = col[2];
00158 }
00159 word = 0;
00160 point++;
00161 }
00162 }
00163 }
00164 catch(int e)
00165 {
00166 ppmFile.close();
00167 throw e;
00168 }
00169 return 0;
00170 }
00171
00172 int cob_3d_mapping_common::PPMReader::mapRGB(const string &file_name,
00173 pcl::PointCloud<pcl::PointXYZRGB> &cloud,
00174 bool remove_undef_points)
00175 {
00176 ifstream ppmFile;
00177 ppmFile.open(file_name.c_str());
00178 if(!ppmFile.is_open())
00179 {
00180 cout << "Could not open \"" << file_name << "\"" << endl;
00181 return (-1);
00182 }
00183
00184 try
00185 {
00186 size_t width, height;
00187 size_t word = 0;
00188 char c;
00189 string value("");
00190
00191
00192 while (word < 4)
00193 {
00194 c = ppmFile.get();
00195 if (!isspace(c))
00196 {
00197 if (c == '#')
00198 {
00199
00200 getline(ppmFile, value);
00201
00202 value = "";
00203 }
00204 else
00205 value += c;
00206 }
00207 else
00208 {
00209 word++;
00210 if (word == 2) width = atoi(value.c_str());
00211 else if(word == 3) height = atoi(value.c_str());
00212 value = "";
00213 }
00214 }
00215
00216
00217 if (width != cloud.width || height != cloud.height)
00218 {
00219 cout << "Size of PPM file ("
00220 << width << " x " << height
00221 << ") does not match the size of point cloud ("
00222 << cloud.width << " x " << cloud.height << ")" << endl;
00223 ppmFile.close();
00224 return(-1);
00225 }
00226
00227
00228 word = 0;
00229 size_t point = 0;
00230 uint8_t col[3];
00231 uint32_t rgb;
00232 while (!ppmFile.eof())
00233 {
00234 value.clear();
00235 ppmFile >> value;
00236 col[word] = atoi(value.c_str());
00237 word++;
00238 if (word == 3)
00239 {
00240 rgb = ((uint32_t)col[0] << 16 | (uint32_t)col[1] << 8 | (uint32_t) col[2]);
00241 cloud[point].rgba = rgb;
00242 if (remove_undef_points && rgb == LBL_UNDEF)
00243 {
00244 cloud.points[point].x = std::numeric_limits<float>::quiet_NaN();
00245 cloud.points[point].y = std::numeric_limits<float>::quiet_NaN();
00246 cloud.points[point].z = std::numeric_limits<float>::quiet_NaN();
00247 }
00248 word = 0;
00249 point++;
00250 }
00251 }
00252 }
00253 catch(int e)
00254 {
00255 ppmFile.close();
00256 throw e;
00257 }
00258 return 0;
00259 }
00260
00261 int cob_3d_mapping_common::PPMWriter::writeRGB(const string &file_name,
00262 const pcl::PointCloud<pcl::PointXYZRGB> &cloud)
00263 {
00264 ofstream ppmFile;
00265 ppmFile.open(file_name.c_str());
00266 if(!ppmFile.is_open())
00267 {
00268 cout << "Could not create \"" << file_name << "\"" << endl;
00269 return (-1);
00270 }
00271
00272 try
00273 {
00274
00275 ppmFile << "P3\n"
00276 << "# Generated from PCD file\n"
00277 << cloud.width << " " << cloud.height << "\n"
00278 << "255\n";
00279
00280 for (size_t i=0; i < cloud.points.size(); i++)
00281 {
00282 ppmFile << (int)cloud.points[i].r << " "
00283 << (int)cloud.points[i].g << " "
00284 << (int)cloud.points[i].b << "\n";
00285 }
00286 ppmFile.close();
00287 }
00288 catch(int e)
00289 {
00290 ppmFile.close();
00291 throw e;
00292 }
00293 return 0;
00294 }
00295
00296 int cob_3d_mapping_common::PPMWriter::writeDepth(const string &file_name,
00297 const pcl::PointCloud<pcl::PointXYZRGB> &cloud)
00298 {
00299 ofstream ppmFile;
00300 ppmFile.open(file_name.c_str());
00301 if(!ppmFile.is_open())
00302 {
00303 cout << "Could not create \"" << file_name << "\"" << endl;
00304 return (-1);
00305 }
00306
00307 try
00308 {
00309
00310 ppmFile << "P3\n"
00311 << "# Generated from PCD file\n"
00312 << cloud.width << " " << cloud.height << "\n"
00313 << "255\n";
00314
00315 for (size_t i = 0; i < cloud.points.size(); i++)
00316 {
00317 #ifdef PCL_VERSION_COMPARE
00318 if (!pcl::isFinite(cloud.points[i]))
00319 #else
00320 if (!pcl::hasValidXYZ(cloud.points[i]))
00321 #endif
00322 continue;
00323
00324 if(!fixed_max_)
00325 max_z_ = max (cloud.points[i].z, max_z_);
00326 if(!fixed_min_)
00327 min_z_ = min (cloud.points[i].z, min_z_);
00328 }
00329 cout << "Max_z = " << max_z_ << " | Min_z = " << min_z_ << endl;
00330 double grd_position;
00331 uint8_t rgb[3];
00332 for (size_t i = 0; i < cloud.points.size(); i++)
00333 {
00334 #ifdef PCL_VERSION_COMPARE
00335 if (!pcl::isFinite(cloud.points[i]))
00336 #else
00337 if (!pcl::hasValidXYZ(cloud.points[i]))
00338 #endif
00339 {
00340 grd_position = (cloud.points[i].z - min_z_) / (max_z_ - min_z_);
00341 cob_3d_mapping_common::getGradientColor(grd_position, rgb);
00342 ppmFile << (int)rgb[0] << " " << (int)rgb[1] << " " << (int)rgb[2] << "\n" ;
00343 }
00344 else
00345 {
00346 ppmFile << "255 255 255\n";
00347 }
00348
00349 }
00350 ppmFile.close();
00351 }
00352 catch(int e)
00353 {
00354 ppmFile.close();
00355 throw e;
00356 }
00357 return 0;
00358 }
00359
00360 int cob_3d_mapping_common::PPMWriter::writeDepthLinear(
00361 const string &file_name,
00362 const pcl::PointCloud<pcl::PointXYZRGB> &cloud)
00363 {
00364 ofstream ppmFile;
00365 ppmFile.open(file_name.c_str());
00366 if(!ppmFile.is_open())
00367 {
00368 cout << "Could not create \"" << file_name << "\"" << endl;
00369 return (-1);
00370 }
00371
00372 try
00373 {
00374
00375 ppmFile << "P3\n"
00376 << "# Generated from PCD file\n"
00377 << cloud.width << " " << cloud.height << "\n"
00378 << "255\n";
00379
00380 float max_z = 0, min_z = 10.0;
00381 for (size_t i = 0; i < cloud.points.size(); i++)
00382 {
00383 #ifdef PCL_VERSION_COMPARE
00384 if (!pcl::isFinite(cloud.points[i]))
00385 #else
00386 if (!pcl::hasValidXYZ(cloud.points[i]))
00387 #endif
00388 continue;
00389
00390 max_z = max (cloud.points[i].z, max_z);
00391 min_z = min (cloud.points[i].z, min_z);
00392 }
00393 max_z = round(1090.0 - (345.0 / max_z));
00394 min_z = round(1090.0 - (345.0 / min_z));
00395 cout << "Max_z = " << max_z << " | Min_z = " << min_z << endl;
00396 double grd_position;
00397 uint8_t rgb[3];
00398 for (size_t i = 0; i < cloud.points.size(); i++)
00399 {
00400 #ifdef PCL_VERSION_COMPARE
00401 if (!pcl::isFinite(cloud.points[i]))
00402 #else
00403 if (!pcl::hasValidXYZ(cloud.points[i]))
00404 #endif
00405 {
00406 grd_position = ( round(1090.0 - (345.0 / cloud.points[i].z) ) - min_z) / (max_z - min_z);
00407 cob_3d_mapping_common::getGradientColor(grd_position, rgb);
00408 ppmFile << (int)rgb[0] << " " << (int)rgb[1] << " " << (int)rgb[2] << "\n" ;
00409 }
00410 else
00411 {
00412 ppmFile << "255 255 255\n";
00413 }
00414 }
00415 ppmFile.close();
00416 }
00417 catch(int e)
00418 {
00419 ppmFile.close();
00420 throw e;
00421 }
00422 return 0;
00423 }
00424
00425 void cob_3d_mapping_common::PPMWriter::setMaxZ (const float &max)
00426 {
00427 fixed_max_ = true;
00428 max_z_ = max;
00429 }
00430
00431 void cob_3d_mapping_common::PPMWriter::setMinZ (const float &min)
00432 {
00433 fixed_min_ = true;
00434 min_z_ = min;
00435 }
00436
00437
00438
00439
00440
00441 uint32_t cob_3d_mapping_common::getGradientColor(double position, uint8_t rgb[])
00442 {
00443
00444 if (position > 1) position = 1;
00445 if (position < 0) position = 0;
00446
00447
00448 int n_bars_max = 4;
00449 double m=n_bars_max * position;
00450 int n=int(m);
00451 double f=m-n;
00452 uint8_t t=int(f*255);
00453
00454 switch (n)
00455 {
00456 case 0:
00457 rgb[0] = 255;
00458 rgb[1] = t;
00459 rgb[2] = 0;
00460 break;
00461 case 1:
00462 rgb[0] = 255 - t;
00463 rgb[1] = 255;
00464 rgb[2] = 0;
00465 break;
00466 case 2:
00467 rgb[0] = 0;
00468 rgb[1] = 255;
00469 rgb[2] = t;
00470 break;
00471 case 3:
00472 rgb[0] = 0;
00473 rgb[1] = 255 - t;
00474 rgb[2] = 255;
00475 break;
00476 case 4:
00477 rgb[0] = t;
00478 rgb[1] = 0;
00479 rgb[2] = 255;
00480 break;
00481 case 5:
00482 rgb[0] = 255;
00483 rgb[1] = 0;
00484 rgb[2] = 255 - t;
00485 break;
00486 };
00487 return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
00488 };