Gazebo Common

API Reference

5.7.1
gz/common/Image.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 #ifndef GZ_COMMON_IMAGE_HH_
18 #define GZ_COMMON_IMAGE_HH_
19 
20 #include <cstring>
21 #include <limits>
22 #include <memory>
23 #include <string>
24 #include <vector>
25 #include <gz/math/Color.hh>
26 
27 #include <gz/common/graphics/Export.hh>
28 
29 #include <gz/utils/ImplPtr.hh>
30 
31 namespace gz
32 {
33  namespace common
34  {
38  {
39  "UNKNOWN_PIXEL_FORMAT",
40  "L_INT8",
41  "L_INT16",
42  "RGB_INT8",
43  "RGBA_INT8",
44  "BGRA_INT8",
45  "RGB_INT16",
46  "RGB_INT32",
47  "BGR_INT8",
48  "BGR_INT16",
49  "BGR_INT32",
50  "R_FLOAT16",
51  "RGB_FLOAT16",
52  "R_FLOAT32",
53  "RGB_FLOAT32",
54  "BAYER_RGGB8",
55  "BAYER_BGGR8",
56  "BAYER_GBRG8",
57  "BAYER_GRBG8",
58  "COMPRESSED_PNG"
59  };
60 
63  class GZ_COMMON_GRAPHICS_VISIBLE Image
64  {
66  public: enum class Channel
67  {
69  RED = 0,
71  GREEN = 1,
73  BLUE = 2,
75  ALPHA = 3
76  };
77 
79  public: enum PixelFormatType
80  {
81  UNKNOWN_PIXEL_FORMAT = 0,
102  // \todo(iche033) COMPRESSED_JPEG is added at the end to
103  // preserve ABI compatibility. Move this enum up when merging
104  // forward to main
105  COMPRESSED_JPEG
106  };
107 
108 
113  const std::string &_format);
114 
117  public: explicit Image(const std::string &_filename = "");
118 
120  public: virtual ~Image();
121 
125  public: int Load(const std::string &_filename);
126 
129  public: void SavePNG(const std::string &_filename);
130 
134 
140  public: void SetFromData(const unsigned char *_data,
141  unsigned int _width,
142  unsigned int _height,
143  Image::PixelFormatType _format);
144 
149  public: void SetFromCompressedData(unsigned char *_data,
150  unsigned int _size,
151  Image::PixelFormatType _format);
152 
157  public: void GZ_DEPRECATED(5) Data(unsigned char **_data,
158  unsigned int &_count) const;
159 
162  public: std::vector<unsigned char> Data() const;
163 
169  public: void GZ_DEPRECATED(5) RGBData(unsigned char **_data,
170  unsigned int &_count) const;
171 
175  public: std::vector<unsigned char> RGBData() const;
176 
182  public: void GZ_DEPRECATED(5) RGBAData(unsigned char **_data,
183  unsigned int &_count) const;
184 
188  public: std::vector<unsigned char> RGBAData() const;
189 
192  public: unsigned int Width() const;
193 
196  public: unsigned int Height() const;
197 
200  public: unsigned int BPP() const;
201 
202  // \brief Get the size of a row of pixel
204  public: int Pitch() const;
205 
208  public: std::string Filename() const;
209 
212  public: PixelFormatType PixelFormat() const;
213 
218  public: math::Color Pixel(const unsigned int _x,
219  const unsigned int _y) const;
220 
223  public: math::Color AvgColor() const;
224 
227  public: math::Color MaxColor() const;
228 
232  public: void Rescale(const int _width, const int _height);
233 
236  public: bool Valid() const;
237 
242  public: std::vector<unsigned char> ChannelData(Channel _channel) const;
243 
260  public: template<typename T>
261  static void ConvertToRGBImage(const void *_data,
262  unsigned int _width, unsigned int _height, Image &_output,
263  T _min = std::numeric_limits<T>::max(),
264  T _max = std::numeric_limits<T>::lowest(), bool _flip = false)
265  {
266  unsigned int samples = _width * _height;
267  unsigned int bufferSize = samples * sizeof(T);
268 
269  auto buffer = std::vector<T>(samples);
270  memcpy(buffer.data(), _data, bufferSize);
271 
272  auto outputRgbBuffer = std::vector<uint8_t>(samples * 3);
273 
274  // use min and max values found in the data if not specified
275  T min = std::numeric_limits<T>::max();
277  if (_min > max)
278  {
279  for (unsigned int i = 0; i < samples; ++i)
280  {
281  auto v = buffer[i];
282  // ignore inf values when computing min/max
283  // cast to float when calling isinf to avoid compile error on
284  // windows
285  if (v > max && !std::isinf(static_cast<float>(v)))
286  max = v;
287  if (v < min && !std::isinf(static_cast<float>(v)))
288  min = v;
289  }
290  }
291  min = math::equal(_min, std::numeric_limits<T>::max()) ? min : _min;
292  max = math::equal(_max, std::numeric_limits<T>::lowest()) ? max : _max;
293 
294  // convert to rgb image
295  // color is grayscale, i.e. r == b == g
296  double range = static_cast<double>(max - min);
297  if (gz::math::equal(range, 0.0))
298  range = 1.0;
299  unsigned int idx = 0;
300  for (unsigned int j = 0; j < _height; ++j)
301  {
302  for (unsigned int i = 0; i < _width; ++i)
303  {
304  auto v = buffer[idx++];
305  double t = static_cast<double>(v - min) / range;
306  if (_flip)
307  t = 1.0 - t;
308  uint8_t r = static_cast<uint8_t>(255*t);
309  unsigned int outIdx = j * _width * 3 + i * 3;
310  outputRgbBuffer[outIdx] = r;
311  outputRgbBuffer[outIdx + 1] = r;
312  outputRgbBuffer[outIdx + 2] = r;
313  }
314  }
315  _output.SetFromData(outputRgbBuffer.data(), _width, _height, RGB_INT8);
316  }
317 
319  GZ_UTILS_IMPL_PTR(dataPtr)
320  };
321  }
322 }
323 #endif