ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ImageFactory.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include <Logging.h>
9 
10 #include "Image.h"
12 
13 namespace cloudViewer {
14 namespace geometry {
15 using namespace cloudViewer;
16 
18  const camera::PinholeCameraIntrinsic &intrinsic) {
19  auto fimage = std::make_shared<Image>();
20  fimage->Prepare(intrinsic.width_, intrinsic.height_, 1, 4);
21  float ffl_inv[2] = {
22  1.0f / (float)intrinsic.GetFocalLength().first,
23  1.0f / (float)intrinsic.GetFocalLength().second,
24  };
25  float fpp[2] = {
26  (float)intrinsic.GetPrincipalPoint().first,
27  (float)intrinsic.GetPrincipalPoint().second,
28  };
29  std::vector<float> xx(intrinsic.width_);
30  std::vector<float> yy(intrinsic.height_);
31  for (int j = 0; j < intrinsic.width_; j++) {
32  xx[j] = (j - fpp[0]) * ffl_inv[0];
33  }
34  for (int i = 0; i < intrinsic.height_; i++) {
35  yy[i] = (i - fpp[1]) * ffl_inv[1];
36  }
37  for (int i = 0; i < intrinsic.height_; i++) {
38  float *fp =
39  (float *)(fimage->data_.data() + i * fimage->BytesPerLine());
40  for (int j = 0; j < intrinsic.width_; j++, fp++) {
41  *fp = sqrtf(xx[j] * xx[j] + yy[i] * yy[i] + 1.0f);
42  }
43  }
44  return fimage;
45 }
46 
47 std::shared_ptr<Image> Image::CreateFloatImage(
48  Image::ColorToIntensityConversionType type /* = WEIGHTED*/) const {
49  auto fimage = std::make_shared<Image>();
50  if (IsEmpty()) {
51  return fimage;
52  }
53  fimage->Prepare(width_, height_, 1, 4);
54  for (int i = 0; i < height_ * width_; i++) {
55  float *p = (float *)(fimage->data_.data() + i * 4);
56  const uint8_t *pi =
58  if (num_of_channels_ == 1) {
59  // grayscale image
60  if (bytes_per_channel_ == 1) {
61  *p = (float)(*pi) / 255.0f;
62  } else if (bytes_per_channel_ == 2) {
63  const uint16_t *pi16 = (const uint16_t *)pi;
64  *p = (float)(*pi16);
65  } else if (bytes_per_channel_ == 4) {
66  const float *pf = (const float *)pi;
67  *p = *pf;
68  }
69  } else if (num_of_channels_ == 3) {
70  if (bytes_per_channel_ == 1) {
72  *p = ((float)(pi[0]) + (float)(pi[1]) + (float)(pi[2])) /
73  3.0f / 255.0f;
74  } else if (type ==
76  *p = (0.2990f * (float)(pi[0]) + 0.5870f * (float)(pi[1]) +
77  0.1140f * (float)(pi[2])) /
78  255.0f;
79  }
80  } else if (bytes_per_channel_ == 2) {
81  const uint16_t *pi16 = (const uint16_t *)pi;
83  *p = ((float)(pi16[0]) + (float)(pi16[1]) +
84  (float)(pi16[2])) /
85  3.0f;
86  } else if (type ==
88  *p = (0.2990f * (float)(pi16[0]) +
89  0.5870f * (float)(pi16[1]) +
90  0.1140f * (float)(pi16[2]));
91  }
92  } else if (bytes_per_channel_ == 4) {
93  const float *pf = (const float *)pi;
95  *p = (pf[0] + pf[1] + pf[2]) / 3.0f;
96  } else if (type ==
98  *p = (0.2990f * pf[0] + 0.5870f * pf[1] + 0.1140f * pf[2]);
99  }
100  }
101  }
102  }
103  return fimage;
104 }
105 
106 template <typename T>
107 std::shared_ptr<Image> Image::CreateImageFromFloatImage() const {
108  auto output = std::make_shared<Image>();
109  if (num_of_channels_ != 1 || bytes_per_channel_ != 4) {
111  "[CreateImageFromFloatImage] Unsupported image format.");
112  }
113 
114  output->Prepare(width_, height_, num_of_channels_, sizeof(T));
115  const float *pi = (const float *)data_.data();
116  T *p = (T *)output->data_.data();
117  for (int i = 0; i < height_ * width_; i++, p++, pi++) {
118  if (sizeof(T) == 1) *p = static_cast<T>(*pi * 255.0f);
119  if (sizeof(T) == 2) *p = static_cast<T>(*pi);
120  }
121  return output;
122 }
123 
124 template std::shared_ptr<Image> Image::CreateImageFromFloatImage<uint8_t>()
125  const;
126 template std::shared_ptr<Image> Image::CreateImageFromFloatImage<uint16_t>()
127  const;
128 
129 ImagePyramid Image::CreatePyramid(size_t num_of_levels,
130  bool with_gaussian_filter /*= true*/) const {
131  std::vector<std::shared_ptr<Image>> pyramid_image;
132  pyramid_image.clear();
133  if ((num_of_channels_ != 1) || (bytes_per_channel_ != 4)) {
134  utility::LogError("[CreateImagePyramid] Unsupported image format.");
135  }
136 
137  for (size_t i = 0; i < num_of_levels; i++) {
138  if (i == 0) {
139  std::shared_ptr<Image> input_copy_ptr = std::make_shared<Image>();
140  *input_copy_ptr = *this;
141  pyramid_image.push_back(input_copy_ptr);
142  } else {
143  if (with_gaussian_filter) {
144  // https://en.wikipedia.org/wiki/Pyramid_(image_processing)
145  auto level_b = pyramid_image[i - 1]->Filter(
147  auto level_bd = level_b->Downsample();
148  pyramid_image.push_back(level_bd);
149  } else {
150  auto level_d = pyramid_image[i - 1]->Downsample();
151  pyramid_image.push_back(level_d);
152  }
153  }
154  }
155  return pyramid_image;
156 }
157 
158 } // namespace geometry
159 } // namespace cloudViewer
char type
Contains the pinhole camera intrinsic parameters.
std::pair< double, double > GetFocalLength() const
Returns the focal length in a tuple of X-axis and Y-axis focal lengths.
std::pair< double, double > GetPrincipalPoint() const
virtual bool IsEmpty() const override
Definition: Image.h:87
ColorToIntensityConversionType
Specifies whether R, G, B channels have the same weight when converting to intensity....
Definition: Image.h:42
@ Weighted
Weighted R, G, B channels: I = 0.299 * R + 0.587 * G + 0.114 * B.
int num_of_channels_
Number of chanels in the image.
Definition: Image.h:223
std::shared_ptr< Image > CreateFloatImage(Image::ColorToIntensityConversionType type=Image::ColorToIntensityConversionType::Weighted) const
Return a gray scaled float type image.
int height_
Height of the image.
Definition: Image.h:221
int bytes_per_channel_
Number of bytes per channel.
Definition: Image.h:225
int width_
Width of the image.
Definition: Image.h:219
std::vector< uint8_t > data_
Image storage buffer.
Definition: Image.h:227
std::shared_ptr< Image > CreateImageFromFloatImage() const
ImagePyramid CreatePyramid(size_t num_of_levels, bool with_gaussian_filter=true) const
Function to create image pyramid.
@ Gaussian3
Gaussian filter of size 3 x 3.
static std::shared_ptr< Image > CreateDepthToCameraDistanceMultiplierFloatImage(const camera::PinholeCameraIntrinsic &intrinsic)
#define LogError(...)
Definition: Logging.h:60
float
std::vector< std::shared_ptr< Image > > ImagePyramid
Typedef and functions for ImagePyramid.
Definition: Image.h:24
Generic file read and write utility for python interface.