00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00050 #include <pcl/io/pcd_io.h>
00051 #include <pcl/console/time.h>
00052 #include <pcl/console/print.h>
00053 #include <pcl/console/parse.h>
00054 #include <pcl/io/vtk_lib_io.h>
00055
00056 #define RED_MULTIPLIER 0.299
00057 #define GREEN_MULTIPLIER 0.587
00058 #define BLUE_MULTIPLIER 0.114
00059 #define MAX_COLOR_INTENSITY 255
00060
00061 using namespace pcl;
00062 using namespace pcl::io;
00063 using namespace pcl::console;
00064
00065 void
00066 printHelp (int, char **argv)
00067 {
00068 std::cout << std::endl;
00069 std::cout << "***************************************************************************" << std::endl;
00070 std::cout << "* *" << std::endl;
00071 std::cout << "* PNG 2 PCD CONVERTER - Usage Guide *" << std::endl;
00072 std::cout << "* *" << std::endl;
00073 std::cout << "***************************************************************************" << std::endl << std::endl;
00074 std::cout << "Usage: " << argv[0] << " [Options] input.png output.pcd" << std::endl << std::endl;
00075 std::cout << "Options:" << std::endl;
00076 std::cout << " -h: Show this help." << std::endl;
00077 std::cout << " -format 0 | 1: Set the format of the output pcd file." << std::endl;
00078 std::cout << " -mode DEFAULT | FORCE_COLOR | FORCE_GRAYSCALE: Set the working mode of the converter." << std::endl;
00079 std::cout << " --intensity_type: FLOAT | UINT_8 Set the desired intensity type" << std::endl;
00080 }
00081
00082 template<typename PointInT> void
00083 saveCloud (const std::string &filename, const PointCloud<PointInT> &cloud, bool format)
00084 {
00085 TicToc tt;
00086 tt.tic ();
00087
00088 print_highlight ("Saving "); print_value ("%s ", filename.c_str ());
00089 savePCDFile (filename, cloud, format);
00090 print_info ("[done, "); print_value ("%g", tt.toc ()); print_info (" ms : "); print_value ("%d", cloud.width * cloud.height); print_info (" points]\n");
00091 }
00092
00093
00094 int
00095 main (int argc, char** argv)
00096 {
00097 print_info ("Convert a PNG file to PCD format. For more information, use: %s -h\n", argv[0]);
00098
00099 if (argc < 3)
00100 {
00101 printHelp (argc, argv);
00102 return (-1);
00103 }
00104
00105
00106 std::vector<int> png_file_indices = parse_file_extension_argument (argc, argv, ".png");
00107 std::vector<int> pcd_file_indices = parse_file_extension_argument (argc, argv, ".pcd");
00108
00109 if (png_file_indices.size () != 1 || pcd_file_indices.size () != 1)
00110 {
00111 print_error ("Need one input PNG file and one output PCD file.\n");
00112 return (-1);
00113 }
00114
00115
00116 bool format = false;
00117 parse_argument (argc, argv, "-format", format);
00118 print_info ("PCD output format: "); print_value ("%s\n", (format ? "binary" : "ascii"));
00119
00120 std::string mode = "DEFAULT";
00121 if (parse_argument (argc, argv, "-mode", mode) != -1)
00122 {
00123 if (! (mode.compare ("DEFAULT") == 0 || mode.compare ("FORCE_COLOR") == 0 || mode.compare ("FORCE_GRAYSCALE") == 0) )
00124 {
00125 std::cout << "Wrong mode name.\n";
00126 printHelp (argc, argv);
00127 exit (-1);
00128 }
00129 }
00130
00131 print_info ("%s mode selected.\n", mode.c_str ());
00132
00133
00134 vtkSmartPointer<vtkImageData> image_data;
00135 vtkSmartPointer<vtkPNGReader> reader = vtkSmartPointer<vtkPNGReader>::New ();
00136 reader->SetFileName (argv[png_file_indices[0]]);
00137 image_data = reader->GetOutput ();
00138 image_data->Update ();
00139
00140
00141 int components = image_data->GetNumberOfScalarComponents();
00142
00143 int dimensions[3];
00144 image_data->GetDimensions (dimensions);
00145
00146 double* pixel = new double [4];
00147 memset (pixel, 0, sizeof(double) * 4);
00148
00149 std::string intensity_type;
00150
00151 if (mode.compare ("DEFAULT") == 0)
00152 {
00153
00154
00155
00156
00157
00158
00159
00160 if (pcl::console::parse_argument (argc, argv, "--intensity_type", intensity_type) != -1)
00161 {
00162 if (intensity_type.compare ("FLOAT") != 0 && intensity_type.compare ("UINT_8") != 0)
00163 {
00164 print_error ("Wrong intensity option.\n");
00165 printHelp (argc, argv);
00166 exit (-1);
00167 }
00168 }
00169 else
00170 {
00171 print_error ("The intensity type must be set to enable the PNG conversion.\n");
00172 exit (-1);
00173 }
00174
00175 PointCloud<Intensity> mono_cloud;
00176 PointCloud<Intensity8u> mono_cloud_u8;
00177 PointCloud<RGB> color_cloud;
00178
00179 int rgb;
00180 int rgba;
00181
00182 switch (components)
00183 {
00184 case 1: if (intensity_type.compare ("FLOAT") == 0)
00185 {
00186 mono_cloud.width = dimensions[0];
00187 mono_cloud.height = dimensions[1];
00188 mono_cloud.is_dense = true;
00189 mono_cloud.points.resize (mono_cloud.width * mono_cloud.height);
00190
00191
00192 for (int z = 0; z < dimensions[2]; z++)
00193 {
00194 for (int y = 0; y < dimensions[1]; y++)
00195 {
00196 for (int x = 0; x < dimensions[0]; x++)
00197 {
00198 pixel[0] = image_data->GetScalarComponentAsDouble(x, y, 0, 0);
00199
00200 Intensity gray;
00201 gray.intensity = static_cast<float> (pixel[0]) / MAX_COLOR_INTENSITY;
00202
00203 mono_cloud (x, dimensions[1] - y - 1) = gray;
00204 }
00205 }
00206 }
00207
00208
00209 saveCloud<Intensity> (argv[pcd_file_indices[0]], mono_cloud, format);
00210 }
00211 else
00212 {
00213 mono_cloud_u8.width = dimensions[0];
00214 mono_cloud_u8.height = dimensions[1];
00215 mono_cloud_u8.is_dense = true;
00216 mono_cloud_u8.points.resize (mono_cloud_u8.width * mono_cloud_u8.height);
00217
00218 for (int z = 0; z < dimensions[2]; z++)
00219 {
00220 for (int y = 0; y < dimensions[1]; y++)
00221 {
00222 for (int x = 0; x < dimensions[0]; x++)
00223 {
00224 pixel[0] = image_data->GetScalarComponentAsDouble(x, y, 0, 0);
00225
00226 Intensity8u gray;
00227 gray.intensity = static_cast<uint8_t> (pixel[0]);
00228
00229 mono_cloud_u8 (x, dimensions[1] - y - 1) = gray;
00230 }
00231 }
00232 }
00233
00234
00235 saveCloud<Intensity8u> (argv[pcd_file_indices[0]], mono_cloud_u8, format);
00236 }
00237 break;
00238
00239 case 3: color_cloud.width = dimensions[0];
00240 color_cloud.height = dimensions[1];
00241 color_cloud.is_dense = true;
00242 color_cloud.points.resize (color_cloud.width * color_cloud.height);
00243
00244 for (int z = 0; z < dimensions[2]; z++)
00245 {
00246 for (int y = 0; y < dimensions[1]; y++)
00247 {
00248 for (int x = 0; x < dimensions[0]; x++)
00249 {
00250 pixel[0] = image_data->GetScalarComponentAsDouble(x, y, 0, 0);
00251 pixel[1] = image_data->GetScalarComponentAsDouble(x, y, 0, 1);
00252 pixel[2] = image_data->GetScalarComponentAsDouble(x, y, 0, 2);
00253
00254 RGB color;
00255 color.r = static_cast<uint8_t> (pixel[0]);
00256 color.g = static_cast<uint8_t> (pixel[1]);
00257 color.b = static_cast<uint8_t> (pixel[2]);
00258
00259 rgb = (static_cast<int> (color.r)) << 16 |
00260 (static_cast<int> (color.g)) << 8 |
00261 (static_cast<int> (color.b));
00262
00263 color.rgb = static_cast<float> (rgb);
00264
00265 color.rgba = static_cast<uint32_t> (rgb);
00266
00267 color_cloud (x, dimensions[1] - y - 1) = color;
00268 }
00269 }
00270 }
00271
00272
00273 saveCloud<RGB> (argv[pcd_file_indices[0]], color_cloud, format);
00274 break;
00275
00276 case 4: color_cloud.width = dimensions[0];
00277 color_cloud.height = dimensions[1];
00278 color_cloud.is_dense = true;
00279 color_cloud.points.resize (color_cloud.width * color_cloud.height);
00280
00281 for (int z = 0; z < dimensions[2]; z++)
00282 {
00283 for (int y = 0; y < dimensions[1]; y++)
00284 {
00285 for (int x = 0; x < dimensions[0]; x++)
00286 {
00287 pixel[0] = image_data->GetScalarComponentAsDouble(x, y, 0, 0);
00288 pixel[1] = image_data->GetScalarComponentAsDouble(x, y, 0, 1);
00289 pixel[2] = image_data->GetScalarComponentAsDouble(x, y, 0, 2);
00290 pixel[3] = image_data->GetScalarComponentAsDouble(x, y, 0, 3);
00291
00292 RGB color;
00293 color.r = static_cast<uint8_t> (pixel[0]);
00294 color.g = static_cast<uint8_t> (pixel[1]);
00295 color.b = static_cast<uint8_t> (pixel[2]);
00296 color.a = static_cast<uint8_t> (pixel[3]);
00297
00298 rgb = (static_cast<int> (color.r)) << 16 |
00299 (static_cast<int> (color.g)) << 8 |
00300 (static_cast<int> (color.b));
00301 rgba = (static_cast<int> (color.a)) << 24 |
00302 (static_cast<int> (color.r)) << 16 |
00303 (static_cast<int> (color.g)) << 8 |
00304 (static_cast<int> (color.b));
00305
00306 color.rgb = static_cast<float> (rgb);
00307 color.rgba = static_cast<uint32_t> (rgba);
00308
00309 color_cloud (x, dimensions[1] - y - 1) = color;
00310 }
00311 }
00312 }
00313
00314
00315 saveCloud<RGB> (argv[pcd_file_indices[0]], color_cloud, format);
00316 break;
00317 }
00318 }
00319 else if (mode.compare ("FORCE_COLOR") == 0)
00320 {
00321
00322
00323
00324
00325
00326 PointCloud<RGB> cloud;
00327 int dimensions[3];
00328 image_data->GetDimensions (dimensions);
00329 cloud.width = dimensions[0];
00330 cloud.height = dimensions[1];
00331 cloud.is_dense = true;
00332 cloud.points.resize (cloud.width * cloud.height);
00333
00334 for (int z = 0; z < dimensions[2]; z++)
00335 {
00336 for (int y = 0; y < dimensions[1]; y++)
00337 {
00338 for (int x = 0; x < dimensions[0]; x++)
00339 {
00340 for (int c = 0; c < components; c++)
00341 pixel[c] = image_data->GetScalarComponentAsDouble(x, y, 0, c);
00342
00343 RGB color;
00344 color.r = 0;
00345 color.g = 0;
00346 color.b = 0;
00347 color.a = 0;
00348 color.rgb = 0.0f;
00349 color.rgba = 0;
00350
00351 int rgb;
00352 int rgba;
00353 switch (components)
00354 {
00355 case 1: color.r = static_cast<uint8_t> (pixel[0]);
00356 color.g = static_cast<uint8_t> (pixel[0]);
00357 color.b = static_cast<uint8_t> (pixel[0]);
00358
00359 rgb = (static_cast<int> (color.r)) << 16 |
00360 (static_cast<int> (color.g)) << 8 |
00361 (static_cast<int> (color.b));
00362
00363 rgba = rgb;
00364 color.rgb = static_cast<float> (rgb);
00365 color.rgba = static_cast<uint32_t> (rgba);
00366 break;
00367
00368 case 3: color.r = static_cast<uint8_t> (pixel[0]);
00369 color.g = static_cast<uint8_t> (pixel[1]);
00370 color.b = static_cast<uint8_t> (pixel[2]);
00371
00372 rgb = (static_cast<int> (color.r)) << 16 |
00373 (static_cast<int> (color.g)) << 8 |
00374 (static_cast<int> (color.b));
00375
00376 rgba = rgb;
00377 color.rgb = static_cast<float> (rgb);
00378 color.rgba = static_cast<uint32_t> (rgba);
00379 break;
00380
00381 case 4: color.r = static_cast<uint8_t> (pixel[0]);
00382 color.g = static_cast<uint8_t> (pixel[1]);
00383 color.b = static_cast<uint8_t> (pixel[2]);
00384 color.a = static_cast<uint8_t> (pixel[3]);
00385
00386 rgb = (static_cast<int> (color.r)) << 16 |
00387 (static_cast<int> (color.g)) << 8 |
00388 (static_cast<int> (color.b));
00389 rgba = (static_cast<int> (color.a)) << 24 |
00390 (static_cast<int> (color.r)) << 16 |
00391 (static_cast<int> (color.g)) << 8 |
00392 (static_cast<int> (color.b));
00393
00394 color.rgb = static_cast<float> (rgb);
00395 color.rgba = static_cast<uint32_t> (rgba);
00396 break;
00397 }
00398
00399 cloud (x, dimensions[1] - y - 1) = color;
00400
00401 }
00402 }
00403 }
00404
00405
00406 saveCloud<RGB> (argv[pcd_file_indices[0]], cloud, format);
00407 }
00408 else if (mode.compare ("FORCE_GRAYSCALE") == 0)
00409 {
00410
00411
00412
00413
00414
00415
00416
00417 PointCloud<Intensity> cloud;
00418 PointCloud<Intensity8u> cloud8u;
00419
00420 if (pcl::console::parse_argument (argc, argv, "--intensity_type", intensity_type) != -1)
00421 {
00422 if (intensity_type.compare ("FLOAT") == 0)
00423 {
00424 cloud.width = dimensions[0];
00425 cloud.height = dimensions[1];
00426 cloud.is_dense = true;
00427 cloud.points.resize (cloud.width * cloud.height);
00428
00429 for (int z = 0; z < dimensions[2]; z++)
00430 {
00431 for (int y = 0; y < dimensions[1]; y++)
00432 {
00433 for (int x = 0; x < dimensions[0]; x++)
00434 {
00435 for (int c = 0; c < components; c++)
00436 pixel[c] = image_data->GetScalarComponentAsDouble(x, y, 0, c);
00437
00438 Intensity gray;
00439
00440 switch (components)
00441 {
00442 case 1: gray.intensity = static_cast<float> (pixel[0]) / MAX_COLOR_INTENSITY;
00443 break;
00444
00445 case 3: gray.intensity = static_cast<float> ( RED_MULTIPLIER * pixel[0] +
00446 GREEN_MULTIPLIER * pixel[1] +
00447 BLUE_MULTIPLIER * pixel[2] ) / MAX_COLOR_INTENSITY;
00448 break;
00449
00450 case 4: gray.intensity = static_cast<float> ( RED_MULTIPLIER * pixel[0] +
00451 GREEN_MULTIPLIER * pixel[1] +
00452 BLUE_MULTIPLIER * pixel[2] ) / MAX_COLOR_INTENSITY;
00453 break;
00454 }
00455
00456 cloud (x, dimensions[1] - y - 1) = gray;
00457 }
00458 }
00459 }
00460
00461
00462 saveCloud<Intensity> (argv[pcd_file_indices[0]], cloud, format);
00463 }
00464 else if (intensity_type.compare ("UINT_8") != 0)
00465 {
00466 cloud8u.width = dimensions[0];
00467 cloud8u.height = dimensions[1];
00468 cloud8u.is_dense = true;
00469 cloud8u.points.resize (cloud8u.width * cloud8u.height);
00470
00471 for (int z = 0; z < dimensions[2]; z++)
00472 {
00473 for (int y = 0; y < dimensions[1]; y++)
00474 {
00475 for (int x = 0; x < dimensions[0]; x++)
00476 {
00477 for (int c = 0; c < components; c++)
00478 pixel[c] = image_data->GetScalarComponentAsDouble(x, y, 0, c);
00479
00480 Intensity8u gray;
00481
00482 switch (components)
00483 {
00484 case 1: gray.intensity = static_cast<uint8_t> (pixel[0]);
00485 break;
00486
00487 case 3: gray.intensity = static_cast<uint8_t> ( RED_MULTIPLIER * pixel[0] +
00488 GREEN_MULTIPLIER * pixel[1] +
00489 BLUE_MULTIPLIER * pixel[2] );
00490 break;
00491
00492 case 4: gray.intensity = static_cast<uint8_t> ( RED_MULTIPLIER * pixel[0] +
00493 GREEN_MULTIPLIER * pixel[1] +
00494 BLUE_MULTIPLIER * pixel[2] );
00495 break;
00496 }
00497
00498 cloud8u (x, dimensions[1] - y - 1) = gray;
00499 }
00500 }
00501 }
00502
00503
00504 saveCloud<Intensity8u> (argv[pcd_file_indices[0]], cloud8u, format);
00505 }
00506 else
00507 {
00508 print_error ("Wrong intensity option.\n");
00509 printHelp (argc, argv);
00510 exit (-1);
00511 }
00512 }
00513 else
00514 {
00515 print_error ("The intensity type must be set to enable the PNG conversion.\n");
00516 exit (-1);
00517 }
00518
00519 }
00520
00521 delete[] pixel;
00522
00523 return 0;
00524 }