curfil  ..
 All Classes Functions Variables Typedefs Friends Groups Pages
image.h
1 #ifndef CURFIL_IMAGE_H
2 #define CURFIL_IMAGE_H
3 
4 #include <boost/shared_ptr.hpp>
5 #include <cassert>
6 #include <cuv/ndarray.hpp>
7 #include <limits>
8 #include <memory>
9 #include <ostream>
10 #include <stdint.h>
11 #include <string>
12 #include <vector>
13 
14 #include "utils.h"
15 
16 namespace curfil {
17 
18 typedef uint8_t LabelType;
19 
24 class RGBColor: public std::vector<uint8_t> {
25 
26 public:
27 
28  RGBColor();
29 
33  RGBColor(uint8_t r, uint8_t g, uint8_t b);
34 
41  RGBColor(const std::string& colorString);
42 
49  std::string toString() const {
50  std::ostringstream o;
51  o << static_cast<int>((*this)[0]) << ",";
52  o << static_cast<int>((*this)[1]) << ",";
53  o << static_cast<int>((*this)[2]);
54  return o.str();
55  }
56 
60  friend std::ostream& operator<<(std::ostream& os, RGBColor const& color) {
61  return os << color.toString();
62  }
63 
64 };
65 
66 LabelType getOrAddColorId(const RGBColor& color, const LabelType& label);
67 
68 void addColorId(const RGBColor& color, const LabelType& label);
69 
79 class Depth
80 {
81 public:
82  Depth() :
83  value(0) {
84  }
85 
89  explicit Depth(const int& value) :
90  value(value) {
91  }
92 
96  explicit Depth(const double& value) :
97  value(1000.0 * value) {
98  if (value != value) { // nan
99  this->value = -1;
100  assert(!isValid());
101  } else {
102  assert(value >= -1);
103  }
104  }
105 
109  bool isValid() const {
110  return (value > 0);
111  }
112 
116  float getFloatValue() const {
117  assert(isValid());
118  return value / 1000.0f;
119  }
120 
124  int getIntValue() const {
125  return value;
126  }
127 
131  Depth operator-(const Depth& other) const {
132  assert(other.getIntValue() >= 0);
133  return Depth(value - other.value);
134  }
135 
139  Depth operator+(const Depth& other) const {
140  assert(other.getIntValue() >= 0);
141  return Depth(value + other.value);
142  }
143 
147  Depth& operator+=(const Depth& other) {
148  assert(other.getIntValue() >= 0);
149  value += other.value;
150  return (*this);
151  }
152 
156  static const Depth INVALID;
157 
158 private:
159 
160  int value;
161 };
162 
174 class RGBDImage {
175 
176 
177 public:
178 
184  explicit RGBDImage(const std::string& filename, const std::string& depthFilename, bool useDepthImages,
185  bool convertToCIELab = true,
186  bool useDepthFilling = false,
187  bool calculateIntegralImage = true);
188 
192  explicit RGBDImage(int width, int height) :
193  filename(""), depthFilename(""),
194  width(width), height(height),
195  colorImage(cuv::extents[COLOR_CHANNELS][height][width], boost::make_shared<cuv::cuda_allocator>()),
196  depthImage(cuv::extents[DEPTH_CHANNELS][height][width], boost::make_shared<cuv::cuda_allocator>()),
197  inCIELab(false), integratedColor(false), integratedDepth(false) {
198  assert(width >= 0 && height >= 0);
199  reset();
200  }
201 
205  RGBDImage(const RGBDImage& other);
206 
210  size_t getSizeInMemory() const {
211  return colorImage.size() * sizeof(float) + depthImage.size() * sizeof(int);
212  }
213 
219  void fillDepth();
220 
224  void reset();
225 
230  return colorImage;
231  }
232 
237  return depthImage;
238  }
239 
245  void calculateDerivative();
246 
252  void calculateIntegral();
253 
259  void dump(std::ostream& out) const;
260 
266  void dumpDepth(std::ostream& out) const;
267 
273  void dumpDepthValid(std::ostream& out) const;
274 
278  void saveColor(const std::string& filename) const;
279 
283  void saveDepth(const std::string& filename) const;
284 
288  const std::string& getFilename() const {
289  return filename;
290  }
291 
295  int getWidth() const {
296  return width;
297  }
298 
302  int getHeight() const {
303  return height;
304  }
305 
309  bool hasIntegratedDepth() const {
310  return integratedDepth;
311  }
312 
316  bool hasIntegratedColor() const {
317  return integratedColor;
318  }
319 
323  bool inImage(int x, int y) const {
324  if (x < 0 || x >= getWidth()) {
325  return false;
326  }
327  if (y < 0 || y >= getHeight()) {
328  return false;
329  }
330  return true;
331  }
332 
336  void setDepth(int x, int y, const Depth& depth) {
337  assert(inImage(x, y));
338 
339  // invalid depth is set to zero which is necessary for integrating
340  depthImage(0, y, x) = depth.isValid() ? depth.getIntValue() : 0;
341  depthImage(1, y, x) = depth.isValid();
342  }
343 
347  Depth getDepth(int x, int y) const {
348  return Depth(static_cast<int>(depthImage(0, y, x)));
349  }
350 
354  int getDepthValid(int x, int y) const {
355  return depthImage(1, y, x);
356  }
357 
366  void setColor(int x, int y, unsigned int channel, float color) {
367  // colorImage(channel, y, x) = color;
368  colorImage.ptr()[channel * getWidth() * getHeight() + y * getWidth() + x] = color;
369  }
370 
377  float getColor(int x, int y, unsigned int channel) const {
378  // return colorImage(channel, y, x);
379  return colorImage.ptr()[channel * getWidth() * getHeight() + y * getWidth() + x];
380  }
381 
385  void resizeImage(int newWidth, int newHeight);
386 
387 private:
388 
389  std::string filename;
390  std::string depthFilename;
391  int width;
392  int height;
395 
396  bool inCIELab;
397  bool integratedColor;
398  bool integratedDepth;
399 
400  static const unsigned int COLOR_CHANNELS = 3;
401  static const unsigned int DEPTH_CHANNELS = 2;
402 
403  void loadDepthImage(const std::string& depthFilename);
404  void loadDummyDepthValues();
405  void fillDepthFromRight();
406  void fillDepthFromLeft();
407  void fillDepthFromBottom();
408  void fillDepthFromTop();
409 
410  template<class T>
412 
413  template<class T>
415 
418 
419 };
420 
427 class LabelImage {
428 
429 private:
430 
431  std::string filename;
432  int width;
433  int height;
435 
436 public:
437 
442  LabelImage(int width, int height) :
443  filename(), width(width), height(height), image(height, width) {
444  image = LabelType();
445  assert(width >= 0 && height >= 0);
446 #ifndef NDEBUG
447  if (width > 0 && height > 0) {
448  assert(image(0, 0) == static_cast<LabelType>(0));
449  }
450 #endif
451  }
452 
456  LabelImage(const std::string& filename);
457 
461  const std::string& getFilename() const {
462  return filename;
463  }
464 
468  bool isInImage(int x, int y) const {
469  if (x < 0 || x >= width)
470  return false;
471  if (y < 0 || y >= height)
472  return false;
473 
474  return true;
475  }
476 
480  void save(const std::string& filename) const;
481 
485  static RGBColor decodeLabel(const LabelType& v);
486 
490  size_t getSizeInMemory() const {
491  return image.size() * sizeof(LabelType);
492  }
493 
497  int getWidth() const {
498  return width;
499  }
500 
504  int getHeight() const {
505  return height;
506  }
507 
511  void setLabel(int x, int y, const LabelType label) {
512  assert(isInImage(x, y));
513  image(y, x) = label;
514  }
515 
519  LabelType getLabel(int x, int y) const {
520  assert(isInImage(x, y));
521  return image(y, x);
522  }
523 
527  static LabelType encodeColor(RGBColor color);
528 
532  void resizeImage(int newWidth, int newHeight, LabelType paddingLabel);
533 
534 }
535 ;
536 
542 
543 public:
547  boost::shared_ptr<RGBDImage> rgbdImage;
551  boost::shared_ptr<LabelImage> labelImage;
552 
553 public:
554 
555  LabeledRGBDImage() :
556  rgbdImage(), labelImage() {
557  }
558 
562  LabeledRGBDImage(const boost::shared_ptr<RGBDImage>& rgbdImage,
563  const boost::shared_ptr<LabelImage>& labelImage);
564 
568  size_t getSizeInMemory() const {
569  return rgbdImage->getSizeInMemory() + labelImage->getSizeInMemory();
570  }
571 
575  const RGBDImage& getRGBDImage() const {
576  return *(rgbdImage.get());
577  }
578 
582  const LabelImage& getLabelImage() const {
583  return *(labelImage.get());
584  }
585 
589  int getWidth() const {
590  return rgbdImage->getWidth();
591  }
592 
596  int getHeight() const {
597  return rgbdImage->getHeight();
598  }
599 
603  void resizeImage(int newWidth, int newHeight, LabelType paddingLabel) const;
604 
608  void calculateIntegral() const;
609 
610 };
611 
612 
616 LabeledRGBDImage loadImagePair(const std::string& filename, bool useCIELab, bool useDepthImages, bool useDepthFilling,
617  bool calculateIntegralImages = true);
618 
623 std::vector<std::string> listImageFilenames(const std::string& folder);
624 
629 std::vector<LabeledRGBDImage> loadImages(const std::string& folder, bool useCIELab, bool useDepthImages, bool useDepthFilling, const std::vector<std::string>& ignoredColors, size_t& numLabels);
630 
631 }
632 
633 #endif