png2pcd.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2012-, Open Perception, Inc.
00006  *
00007  *  All rights reserved.
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *
00013  *   * Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *   * Redistributions in binary form must reproduce the above
00016  *     copyright notice, this list of conditions and the following
00017  *     disclaimer in the documentation and/or other materials provided
00018  *     with the distribution.
00019  *   * Neither the name of the copyright holder(s) nor the names of its
00020  *     contributors may be used to endorse or promote products derived
00021  *     from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  * $Id: png2pcd.cpp 6766 2012-08-09 16:44:37Z gioia $
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   // Parse the command line arguments for .vtk and .ply files
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   // Command line parsing
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   // Load the input file
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   // Retrieve the entries from the image data and copy them into the output RGB cloud
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     // If the input image is a monochrome image the output cloud will be:
00155     // - a pcl::PointCloud<pcl::Intensity> if the intensity_type flag is set to FLOAT;
00156     // - a pcl::PointCloud<pcl::Intensity8u> if the intensity_type flag is set to UINT_8;
00157     // otherwise it will be a pcl::PointCloud<pcl::RGB>.
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]; // This indicates that the point cloud is organized
00188         mono_cloud.is_dense = true;
00189         mono_cloud.points.resize (mono_cloud.width * mono_cloud.height);
00190 
00191         // TODO: is this Z loop needed?
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         // Save the point cloud into a PCD file
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]; // This indicates that the point cloud is organized
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         // Save the point cloud into a PCD file
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]; // This indicates that the point cloud is organized
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       // Save the point cloud into a PCD file
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]; // This indicates that the point cloud is organized
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       // Save the point cloud into a PCD file
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     // Force the output cloud to be a pcl::PointCloud<pcl::RGB> even if the input image is a
00323     // monochrome image.
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]; // This indicates that the point cloud is organized
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     // Save the point cloud into a PCD file
00406     saveCloud<RGB> (argv[pcd_file_indices[0]], cloud, format);
00407   }
00408   else if (mode.compare ("FORCE_GRAYSCALE") == 0)
00409   {
00410     //
00411     // Force the output cloud to be:
00412     // - a pcl::PointCloud<pcl::Intensity> if the intensity_type flag is set to FLOAT;
00413     // - a pcl::PointCloud<pcl::Intensity8u> if the intensity_type flag is set to UINT_8;
00414     // even if the input image is a RGB or a RGBA image.
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]; // This indicates that the point cloud is organized
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         // Save the point cloud into a PCD file
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]; // This indicates that the point cloud is organized
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         // Save the point cloud into a PCD file
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 }


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:28:18