Point Cloud Library (PCL)  1.7.1
png_io.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, Willow Garage, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of the copyright holder(s) nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id$
37  * Authors: Anatoly Baksheev
38  */
39 
40 #ifndef PCL_IO_PNG_IO_H_
41 #define PCL_IO_PNG_IO_H_
42 
43 #include <pcl/pcl_macros.h>
44 #include <pcl/point_cloud.h>
45 #include <pcl/point_types.h>
46 #include <pcl/console/print.h>
47 #include <string>
48 #include <vector>
49 #include <pcl/io/point_cloud_image_extractors.h>
50 
51 namespace pcl
52 {
53  namespace io
54  {
55  /** \brief Saves 8-bit encoded image to PNG file.
56  * \param[in] file_name the name of the file to write to disk
57  * \param[in] mono_image image grayscale data
58  * \param[in] width image width
59  * \param[in] height image height
60  * \param[in] channels number of channels
61  * \ingroup io
62  */
63  PCL_EXPORTS void
64  saveCharPNGFile (const std::string& file_name, const unsigned char *mono_image, int width, int height, int channels);
65 
66  /** \brief Saves 16-bit encoded image to PNG file.
67  * \param[in] file_name the name of the file to write to disk
68  * \param[in] short_image image short data
69  * \param[in] width image width
70  * \param[in] height image height
71  * \param[in] channels number of channels
72  * \ingroup io
73  */
74  PCL_EXPORTS void
75  saveShortPNGFile (const std::string& file_name, const unsigned short *short_image, int width, int height, int channels);
76 
77  /** \brief Saves 8-bit encoded RGB image to PNG file.
78  * \param[in] file_name the name of the file to write to disk
79  * \param[in] rgb_image image rgb data
80  * \param[in] width image width
81  * \param[in] height image height
82  * \ingroup io
83  */
84  PCL_EXPORTS void
85  saveRgbPNGFile (const std::string& file_name, const unsigned char *rgb_image, int width, int height)
86  {
87  saveCharPNGFile(file_name, rgb_image, width, height, 3);
88  }
89 
90  /** \brief Saves 8-bit grayscale cloud as image to PNG file.
91  * \param[in] file_name the name of the file to write to disk
92  * \param[in] cloud point cloud to save
93  * \ingroup io
94  */
95  void
96  savePNGFile (const std::string& file_name, const pcl::PointCloud<unsigned char>& cloud)
97  {
98  saveCharPNGFile(file_name, &cloud.points[0], cloud.width, cloud.height, 1);
99  }
100 
101  /** \brief Saves 16-bit grayscale cloud as image to PNG file.
102  * \param[in] file_name the name of the file to write to disk
103  * \param[in] cloud point cloud to save
104  * \ingroup io
105  */
106  void
107  savePNGFile (const std::string& file_name, const pcl::PointCloud<unsigned short>& cloud)
108  {
109  saveShortPNGFile(file_name, &cloud.points[0], cloud.width, cloud.height, 1);
110  }
111 
112  /** \brief Saves a PCLImage (formely ROS sensor_msgs::Image) to PNG file.
113  * \param[in] file_name the name of the file to write to disk
114  * \param[in] image image to save
115  * \ingroup io
116  * \note Currently only "rgb8", "mono8", and "mono16" image encodings are supported.
117  */
118  void
119  savePNGFile (const std::string& file_name, const pcl::PCLImage& image)
120  {
121  if (image.encoding == "rgb8")
122  {
123  saveRgbPNGFile(file_name, &image.data[0], image.width, image.height);
124  }
125  else if (image.encoding == "mono8")
126  {
127  saveCharPNGFile(file_name, &image.data[0], image.width, image.height, 1);
128  }
129  else if (image.encoding == "mono16")
130  {
131  saveShortPNGFile(file_name, reinterpret_cast<const unsigned short*>(&image.data[0]), image.width, image.height, 1);
132  }
133  else
134  {
135  PCL_ERROR ("[pcl::io::savePNGFile] Unsupported image encoding \"%s\".\n", image.encoding.c_str ());
136  }
137  }
138 
139  /** \brief Saves RGB fields of cloud as image to PNG file.
140  * \param[in] file_name the name of the file to write to disk
141  * \param[in] cloud point cloud to save
142  * \ingroup io
143  */
144  PCL_DEPRECATED (template <typename T> void savePNGFile (const std::string& file_name, const pcl::PointCloud<T>& cloud),
145  "pcl::io::savePNGFile<typename T> (file_name, cloud) is deprecated, please use a new generic "
146  "function pcl::io::savePNGFile (file_name, cloud, field_name) with \"rgb\" as the field name."
147  );
148  template <typename T> void
149  savePNGFile (const std::string& file_name, const pcl::PointCloud<T>& cloud)
150  {
151  std::vector<unsigned char> data(cloud.width * cloud.height * 3);
152 
153  for (size_t i = 0; i < cloud.points.size (); ++i)
154  {
155  data[i*3 + 0] = cloud.points[i].r;
156  data[i*3 + 1] = cloud.points[i].g;
157  data[i*3 + 2] = cloud.points[i].b;
158  }
159  saveRgbPNGFile(file_name, &data[0], cloud.width, cloud.height);
160  }
161 
162  /** \brief Saves Labeled Point cloud as image to PNG file.
163  * \param[in] file_name the name of the file to write to disk
164  * \param[in] cloud point cloud to save
165  * \ingroup io
166  * Warning: Converts to 16 bit (for png), labels using more than 16 bits will cause problems
167  */
168  PCL_DEPRECATED (void savePNGFile (const std::string& file_name, const pcl::PointCloud<pcl::PointXYZL>& cloud),
169  "pcl::io::savePNGFile (file_name, cloud) is deprecated, please use a new generic function "
170  "pcl::io::savePNGFile (file_name, cloud, field_name) with \"label\" as the field name."
171  );
172  void
173  savePNGFile (const std::string& file_name, const pcl::PointCloud<pcl::PointXYZL>& cloud)
174  {
175  std::vector<unsigned short> data(cloud.width * cloud.height);
176  for (size_t i = 0; i < cloud.points.size (); ++i)
177  {
178  data[i] = static_cast<unsigned short> (cloud.points[i].label);
179  }
180  saveShortPNGFile(file_name, &data[0], cloud.width, cloud.height,1);
181  }
182 
183  /** \brief Saves the data from the specified field of the point cloud as image to PNG file.
184  * \param[in] file_name the name of the file to write to disk
185  * \param[in] cloud point cloud to save
186  * \param[in] field_name the name of the field to extract data from
187  * \ingroup io
188  */
189  template <typename PointT> void
190  savePNGFile (const std::string& file_name, const pcl::PointCloud<PointT>& cloud, const std::string& field_name)
191  {
192  typedef typename PointCloudImageExtractor<PointT>::Ptr PointCloudImageExtractorPtr;
193  PointCloudImageExtractorPtr pcie;
194  if (field_name == "normal")
195  {
196  pcie = PointCloudImageExtractorPtr (new PointCloudImageExtractorFromNormalField<PointT>);
197  }
198  else if (field_name == "rgb")
199  {
200  pcie = PointCloudImageExtractorPtr (new PointCloudImageExtractorFromRGBField<PointT>);
201  }
202  else if (field_name == "label")
203  {
204  pcie = PointCloudImageExtractorPtr (new PointCloudImageExtractorFromLabelField<PointT>);
205  }
206  else if (field_name == "z")
207  {
208  pcie = PointCloudImageExtractorPtr (new PointCloudImageExtractorFromZField<PointT>);
209  }
210  else if (field_name == "curvature")
211  {
212  pcie = PointCloudImageExtractorPtr (new PointCloudImageExtractorFromCurvatureField<PointT>);
213  }
214  else if (field_name == "intensity")
215  {
216  pcie = PointCloudImageExtractorPtr (new PointCloudImageExtractorFromIntensityField<PointT>);
217  }
218  else
219  {
220  PCL_ERROR ("[pcl::io::savePNGFile] Unsupported field \"%s\".\n", field_name.c_str ());
221  return;
222  }
223  pcl::PCLImage image;
224  if (pcie->extract (cloud, image))
225  {
226  savePNGFile(file_name, image);
227  }
228  else
229  {
230  PCL_ERROR ("[pcl::io::savePNGFile] Failed to extract an image from \"%s\" field.\n", field_name.c_str());
231  }
232  }
233 
234  }
235 }
236 
237 #endif //#ifndef PCL_IO_PNG_IO_H_