Nav2 Navigation Stack - jazzy  jazzy
ROS 2 Navigation Stack
image.hpp
1 // Copyright (c) 2023 Andrey Ryzhikov
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef NAV2_COSTMAP_2D__DENOISE__IMAGE_HPP_
16 #define NAV2_COSTMAP_2D__DENOISE__IMAGE_HPP_
17 
18 #include <cstddef>
19 #include <stdexcept>
20 
21 namespace nav2_costmap_2d
22 {
23 
31 template<class T>
32 class Image
33 {
34 public:
36  Image() = default;
37 
46  Image(size_t rows, size_t columns, T * data, size_t step);
47 
53  Image(const Image & other);
54 
58  Image(Image && other) noexcept;
59 
61  size_t rows() const {return rows_;}
62 
64  size_t columns() const {return columns_;}
65 
67  bool empty() const {return rows_ == 0 || columns_ == 0;}
68 
70  size_t step() const {return step_;}
71 
76  T * row(size_t row);
77 
79  const T * row(size_t row) const;
80 
88  template<class Functor>
89  void forEach(Functor && fn);
90 
98  template<class Functor>
99  void forEach(Functor && fn) const;
117  template<class TargetElement, class Converter>
118  void convert(Image<TargetElement> & target, Converter && converter) const;
119 
120 private:
121  T * data_start_{};
122  size_t rows_{};
123  size_t columns_{};
124  size_t step_{};
125 };
126 
127 template<class T>
128 Image<T>::Image(size_t rows, size_t columns, T * data, size_t step)
129 : rows_{rows}, columns_{columns}, step_{step}
130 {
131  data_start_ = data;
132 }
133 
134 template<class T>
135 Image<T>::Image(const Image & other)
136 : data_start_{other.data_start_},
137  rows_{other.rows_}, columns_{other.columns_}, step_{other.step_} {}
138 
139 template<class T>
140 Image<T>::Image(Image && other) noexcept
141 : data_start_{other.data_start_},
142  rows_{other.rows_}, columns_{other.columns_}, step_{other.step_} {}
143 
144 template<class T>
145 T * Image<T>::row(size_t row)
146 {
147  return const_cast<T *>( static_cast<const Image<T> &>(*this).row(row) );
148 }
149 
150 template<class T>
151 const T * Image<T>::row(size_t row) const
152 {
153  return data_start_ + row * step_;
154 }
155 
156 template<class T>
157 template<class Functor>
158 void Image<T>::forEach(Functor && fn)
159 {
160  static_cast<const Image<T> &>(*this).forEach(
161  [&](const T & pixel) {
162  fn(const_cast<T &>(pixel));
163  });
164 }
165 
166 template<class T>
167 template<class Functor>
168 void Image<T>::forEach(Functor && fn) const
169 {
170  const T * rowPtr = row(0);
171 
172  for (size_t row = 0; row < rows(); ++row) {
173  const T * rowEnd = rowPtr + columns();
174 
175  for (const T * pixel = rowPtr; pixel != rowEnd; ++pixel) {
176  fn(*pixel);
177  }
178  rowPtr += step();
179  }
180 }
181 
182 template<class T>
183 template<class TargetElement, class Converter>
184 void Image<T>::convert(Image<TargetElement> & target, Converter && converter) const
185 {
186  if (rows() != target.rows() || columns() != target.columns()) {
187  throw std::logic_error("Image::convert. The source and target images size are different");
188  }
189  const T * source_row = row(0);
190  TargetElement * target_row = target.row(0);
191 
192  for (size_t row = 0; row < rows(); ++row) {
193  const T * rowInEnd = source_row + columns();
194  const T * src = source_row;
195  TargetElement * trg = target_row;
196 
197  for (; src != rowInEnd; ++src, ++trg) {
198  converter(*src, *trg);
199  }
200  source_row += step();
201  target_row += target.step();
202  }
203 }
204 
205 } // namespace nav2_costmap_2d
206 
207 #endif // NAV2_COSTMAP_2D__DENOISE__IMAGE_HPP_
Image with pixels of type T Сan own data, be a wrapper over some memory buffer, or refer to a fragmen...
Definition: image.hpp:33
void forEach(Functor &&fn)
Read (and modify, if need) each pixel sequentially.
Definition: image.hpp:158
bool empty() const
Definition: image.hpp:67
T * row(size_t row)
Definition: image.hpp:145
void convert(Image< TargetElement > &target, Converter &&converter) const
Convert each pixel to corresponding pixel of target using a custom function.
Definition: image.hpp:184
Image()=default
Create empty image.
size_t columns() const
Definition: image.hpp:64
size_t rows() const
Definition: image.hpp:61
size_t step() const
Definition: image.hpp:70