GridMapCvConverter.hpp
Go to the documentation of this file.
1 /*
2  * GridMapCvConverter.hpp
3  *
4  * Created on: Apr 14, 2016
5  * Author: Péter Fankhauser
6  * Institute: ETH Zurich, ANYbotics
7  */
8 
9 #pragma once
10 
12 
13 // OpenCV
14 #include <cv_bridge/cv_bridge.h>
15 
16 // STD
17 #include <iostream>
18 
19 namespace grid_map {
20 
25 {
26  public:
36  static bool initializeFromImage(const cv::Mat& image, const double resolution,
37  grid_map::GridMap& gridMap, const grid_map::Position& position)
38  {
39  const double lengthX = resolution * image.rows;
40  const double lengthY = resolution * image.cols;
41  Length length(lengthX, lengthY);
42  gridMap.setGeometry(length, resolution, position);
43  return true;
44  }
45 
58  template<typename Type_, int NChannels_>
59  static bool addLayerFromImage(const cv::Mat& image, const std::string& layer,
60  grid_map::GridMap& gridMap, const float lowerValue = 0.0,
61  const float upperValue = 1.0, const double alphaThreshold = 0.5)
62  {
63  if (gridMap.getSize()(0) != image.rows || gridMap.getSize()(1) != image.cols) {
64  std::cerr << "Image size does not correspond to grid map size!" << std::endl;
65  return false;
66  }
67 
68  bool isColor = false;
69  if (image.channels() >= 3) isColor = true;
70  bool hasAlpha = false;
71  if (image.channels() >= 4) hasAlpha = true;
72 
73  cv::Mat imageMono;
74  if (isColor && !hasAlpha) {
75  cv::cvtColor(image, imageMono, CV_BGR2GRAY);
76  } else if (isColor && hasAlpha) {
77  cv::cvtColor(image, imageMono, CV_BGRA2GRAY);
78  } else if (!isColor && !hasAlpha){
79  imageMono = image;
80  } else {
81  std::cerr << "Something went wrong when adding grid map layer form image!" << std::endl;
82  return false;
83  }
84 
85  const float mapValueDifference = upperValue - lowerValue;
86 
87  float maxImageValue;
88  if (std::is_same<Type_, float>::value || std::is_same<Type_, double>::value) {
89  maxImageValue = 1.0;
90  } else if (std::is_same<Type_, unsigned short>::value || std::is_same<Type_, unsigned char>::value) {
91  maxImageValue = (float)std::numeric_limits<Type_>::max();
92  } else {
93  std::cerr << "This image type is not supported." << std::endl;
94  return false;
95  }
96 
97  const Type_ alphaTreshold = (Type_)(alphaThreshold * maxImageValue);
98 
99  gridMap.add(layer);
100  grid_map::Matrix& data = gridMap[layer];
101 
102  for (GridMapIterator iterator(gridMap); !iterator.isPastEnd(); ++iterator) {
103  const grid_map::Index gridMapIndex = *iterator;
104  const grid_map::Index imageIndex = iterator.getUnwrappedIndex();
105 
106  // Check for alpha layer.
107  if (hasAlpha) {
108  const Type_ alpha = image.at<cv::Vec<Type_, NChannels_>>(imageIndex(0), imageIndex(1))[NChannels_ - 1];
109  if (alpha < alphaTreshold) continue;
110  }
111 
112  // Compute value.
113  const Type_ imageValue = imageMono.at<Type_>(imageIndex(0), imageIndex(1));
114  const float mapValue = lowerValue + mapValueDifference * ((float) imageValue / maxImageValue);
115  data(gridMapIndex(0), gridMapIndex(1)) = mapValue;
116  }
117 
118  return true;
119  }
120 
128  template<typename Type_, int NChannels_>
129  static bool addColorLayerFromImage(const cv::Mat& image, const std::string& layer,
130  grid_map::GridMap& gridMap)
131  {
132  if (gridMap.getSize()(0) != image.rows || gridMap.getSize()(1) != image.cols) {
133  std::cerr << "Image size does not correspond to grid map size!" << std::endl;
134  return false;
135  }
136 
137  bool hasAlpha = false;
138  if (image.channels() >= 4) hasAlpha = true;
139 
140  cv::Mat imageRGB;
141  if (hasAlpha) {
142  cv::cvtColor(image, imageRGB, CV_BGRA2RGB);
143  } else {
144  imageRGB = image;
145  }
146 
147  gridMap.add(layer);
148 
149  for (GridMapIterator iterator(gridMap); !iterator.isPastEnd(); ++iterator) {
150  const auto& cvColor = imageRGB.at<cv::Vec<Type_, 3>>((*iterator)(0), (*iterator)(1));
151  Eigen::Vector3i colorVector;
152  colorVector(0) = cvColor[0];
153  colorVector(1) = cvColor[1];
154  colorVector(2) = cvColor[2];
155  colorVectorToValue(colorVector, gridMap.at(layer, *iterator));
156  }
157 
158  return true;
159  }
160 
173  template<typename Type_, int NChannels_>
174  static bool toImage(const grid_map::GridMap& gridMap, const std::string& layer,
175  const int encoding, cv::Mat& image)
176  {
177  const float minValue = gridMap.get(layer).minCoeffOfFinites();
178  const float maxValue = gridMap.get(layer).maxCoeffOfFinites();
179  return toImage<Type_, NChannels_>(gridMap, layer, encoding, minValue, maxValue, image);
180  }
181 
192  template<typename Type_, int NChannels_>
193  static bool toImage(const grid_map::GridMap& gridMap, const std::string& layer,
194  const int encoding, const float lowerValue, const float upperValue,
195  cv::Mat& image)
196  {
197  // Initialize image.
198  if (gridMap.getSize()(0) > 0 && gridMap.getSize()(1) > 0) {
199  image = cv::Mat::zeros(gridMap.getSize()(0), gridMap.getSize()(1), encoding);
200  } else {
201  std::cerr << "Invalid grid map?" << std::endl;
202  return false;
203  }
204 
205  // Get max image value.
206  Type_ imageMax;
207  if (std::is_same<Type_, float>::value || std::is_same<Type_, double>::value) {
208  imageMax = 1.0;
209  } else if (std::is_same<Type_, unsigned short>::value || std::is_same<Type_, unsigned char>::value) {
210  imageMax = (Type_)std::numeric_limits<Type_>::max();
211  } else {
212  std::cerr << "This image type is not supported." << std::endl;
213  return false;
214  }
215 
216  // Clamp outliers.
217  grid_map::GridMap map = gridMap;
218  map.get(layer) = map.get(layer).unaryExpr(grid_map::Clamp<float>(lowerValue, upperValue));
219  const grid_map::Matrix& data = map[layer];
220 
221  // Convert to image.
222  bool isColor = false;
223  if (image.channels() >= 3) isColor = true;
224  bool hasAlpha = false;
225  if (image.channels() >= 4) hasAlpha = true;
226 
227  for (GridMapIterator iterator(map); !iterator.isPastEnd(); ++iterator) {
228  const Index index(*iterator);
229  const float& value = data(index(0), index(1));
230  if (std::isfinite(value)) {
231  const Type_ imageValue = (Type_)(((value - lowerValue) / (upperValue - lowerValue)) * (float)imageMax);
232  const Index imageIndex(iterator.getUnwrappedIndex());
233  unsigned int channel = 0;
234  image.at<cv::Vec<Type_, NChannels_>>(imageIndex(0), imageIndex(1))[channel] = imageValue;
235 
236  if (isColor) {
237  image.at<cv::Vec<Type_, NChannels_>>(imageIndex(0), imageIndex(1))[++channel] = imageValue;
238  image.at<cv::Vec<Type_, NChannels_>>(imageIndex(0), imageIndex(1))[++channel] = imageValue;
239  }
240  if (hasAlpha) {
241  image.at<cv::Vec<Type_, NChannels_>>(imageIndex(0), imageIndex(1))[++channel] = imageMax;
242  }
243  }
244  }
245 
246  return true;
247  }
248 
249 };
250 
251 } /* namespace */
static bool toImage(const grid_map::GridMap &gridMap, const std::string &layer, const int encoding, const float lowerValue, const float upperValue, cv::Mat &image)
static bool toImage(const grid_map::GridMap &gridMap, const std::string &layer, const int encoding, cv::Mat &image)
Eigen::Array2i Index
void setGeometry(const Length &length, const double resolution, const Position &position=Position::Zero())
Eigen::MatrixXf Matrix
static bool addColorLayerFromImage(const cv::Mat &image, const std::string &layer, grid_map::GridMap &gridMap)
static bool initializeFromImage(const cv::Mat &image, const double resolution, grid_map::GridMap &gridMap, const grid_map::Position &position)
static bool addLayerFromImage(const cv::Mat &image, const std::string &layer, grid_map::GridMap &gridMap, const float lowerValue=0.0, const float upperValue=1.0, const double alphaThreshold=0.5)
Eigen::Vector2d Position
bool colorVectorToValue(const Eigen::Vector3i &colorVector, unsigned long &colorValue)
const Matrix & get(const std::string &layer) const
float & at(const std::string &layer, const Index &index)
void add(const std::string &layer, const double value=NAN)
Eigen::Array2d Length
const Size & getSize() const


grid_map_cv
Author(s): Péter Fankhauser , Magnus Gärtner
autogenerated on Tue Jun 1 2021 02:13:32