image.h
Go to the documentation of this file.
1 /*
2 * ECVL - European Computer Vision Library
3 * Version: 0.3.4
4 * copyright (c) 2021, Università degli Studi di Modena e Reggio Emilia (UNIMORE), AImageLab
5 * Authors:
6 * Costantino Grana (costantino.grana@unimore.it)
7 * Federico Bolelli (federico.bolelli@unimore.it)
8 * Michele Cancilla (michele.cancilla@unimore.it)
9 * Laura Canalini (laura.canalini@unimore.it)
10 * Stefano Allegretti (stefano.allegretti@unimore.it)
11 * All rights reserved.
12 */
13 
14 #ifndef ECVL_IMAGE_H_
15 #define ECVL_IMAGE_H_
16 
17 #include <algorithm>
18 #include <numeric>
19 #include <stdexcept>
20 #include <vector>
21 
22 #include <opencv2/core.hpp>
23 
24 #include "datatype.h"
25 #include "hal.h"
26 #include "iterators.h"
27 #include "datatype_matrix.h"
28 #include "type_promotion.h"
29 #include "standard_errors.h"
30 
31 namespace ecvl
32 {
33 template<typename T>
34 int vsize(const std::vector<T>& v)
35 {
36  return static_cast<int>(v.size());
37 }
38 
39 class MetaData
40 {
41 public:
42  virtual bool Query(const std::string& name, std::string& value) const = 0;
43  virtual ~MetaData() {}
44 };
45 
50 enum class ColorType
51 {
52  none,
53  GRAY,
54  RGB,
55  RGBA,
56  BGR,
57  HSV,
58  YCbCr,
59 };
60 
61 class Image;
62 
63 template <DataType DT>
64 class View;
65 
66 template <DataType DT>
67 class ConstView;
68 
72 class Image
73 {
74 protected:
86  {
87  // Compute strides
88  strides_ = { elemsize_ };
89  int dsize = vsize(dims_);
90  for (int i = 0; i < dsize - 1; ++i) {
91  strides_.push_back(strides_[i] * dims_[i]);
92  }
93  }
94 
102  {
103  return std::accumulate(std::begin(dims_), std::end(dims_), size_t(elemsize_), std::multiplies<size_t>());
104  }
105 
113  {
115  }
116 
118 
119 public:
122  uint8_t elemsize_;
123  std::vector<int> dims_;
125  std::vector<int> strides_;
130  std::string channels_;
163  std::vector<float> spacings_;
168  uint8_t* data_;
175  size_t datasize_;
176  bool contiguous_;
187  Device dev_;
198  template<typename T>
199  Iterator<T> Begin() { return Iterator<T>(*this); }
200 
206  template<typename T>
207  Iterator<T> End() { return Iterator<T>(*this, dims_); }
208 
215  template<typename T>
216  ConstIterator<T> Begin() const { return ConstIterator<T>(*this); }
217 
223  template<typename T>
224  ConstIterator<T> End() const { return ConstIterator<T>(*this, dims_); }
225 
232  template<typename T>
234 
240  template<typename T>
242 
249  template<typename T>
251 
256  template<typename T>
258 
263  Image() :
266  dims_{},
267  spacings_{},
268  strides_{},
269  channels_{},
271  data_{ nullptr },
272  datasize_{ 0 },
273  contiguous_{ true },
274  meta_{ nullptr },
275  hal_{ nullptr },
276  dev_{ Device::NONE }
277  {
278  }
279 
284  Image(const std::vector<int>& dims, DataType elemtype, std::string channels, ColorType colortype,
285  const std::vector<float>& spacings = std::vector<float>(), Device dev = Device::CPU) :
286  elemtype_{ elemtype },
288  dims_{ dims },
289  spacings_{ spacings },
290  strides_{},
291  channels_{ move(channels) },
292  colortype_{ colortype },
293  data_{ nullptr },
294  datasize_{ 0 },
295  contiguous_{ true },
296  meta_{ nullptr },
297  hal_{ HardwareAbstractionLayer::Factory(dev) },
298  dev_{ dev }
299  {
300  if (dims_.size() != channels_.size()) {
301  throw std::runtime_error("Number of dimensions must match number of channels.");
302  }
303  hal_->Create(*this);
304  }
305 
312  Image(const Image& img) :
313  elemtype_{ img.elemtype_ },
314  elemsize_{ img.elemsize_ },
315  dims_{ img.dims_ },
316  spacings_{ img.spacings_ },
317  strides_{ img.strides_ },
318  channels_{ img.channels_ },
319  colortype_{ img.colortype_ },
320  data_{},
321  datasize_{ img.datasize_ },
322  contiguous_{ img.contiguous_ },
323  meta_{ img.meta_ },
324  hal_{ img.hal_ },
325  dev_{ img.dev_ }
326  {
327  hal_->Copy(img, *this);
328  }
329 
334  Image(Image&& img)
335  {
336  elemtype_ = img.elemtype_;
337  elemsize_ = img.elemsize_;
338  dims_ = img.dims_;
339  spacings_ = img.spacings_;
340  strides_ = img.strides_;
341  channels_ = img.channels_;
342  colortype_ = img.colortype_;
343  data_ = img.data_;
344  datasize_ = img.datasize_;
345  contiguous_ = img.contiguous_;
346  meta_ = img.meta_;
347  hal_ = img.hal_;
348  dev_ = img.dev_;
349  img.hal_ = nullptr; // This disables destruction of rhs.data_
350  }
351 
352  friend void swap(Image& lhs, Image& rhs)
353  {
354  using std::swap;
355  swap(lhs.elemtype_, rhs.elemtype_);
356  swap(lhs.elemsize_, rhs.elemsize_);
357  swap(lhs.dims_, rhs.dims_);
358  swap(lhs.spacings_, rhs.spacings_);
359  swap(lhs.strides_, rhs.strides_);
360  swap(lhs.channels_, rhs.channels_);
361  swap(lhs.colortype_, rhs.colortype_);
362  swap(lhs.data_, rhs.data_);
363  swap(lhs.datasize_, rhs.datasize_);
364  swap(lhs.contiguous_, rhs.contiguous_);
365  swap(lhs.meta_, rhs.meta_);
366  swap(lhs.hal_, rhs.hal_);
367  swap(lhs.dev_, rhs.dev_);
368  }
369 
370  Image& operator=(const Image& rhs)
371  {
372  // Self-assignment detection
373  if (this != &rhs) {
374  Image tmp = rhs; // Copy and swap because I'm lazy, but still want super cheap self assignment
375  swap(*this, tmp);
376  }
377  return *this;
378  }
379 
381  {
382  assert(this != &rhs);
383  elemtype_ = rhs.elemtype_;
384  elemsize_ = rhs.elemsize_;
385  dims_ = rhs.dims_;
386  spacings_ = rhs.spacings_;
387  strides_ = rhs.strides_;
388  channels_ = rhs.channels_;
389  colortype_ = rhs.colortype_;
390  // Release any resource we are holding
391  if (hal_) {
392  hal_->MemDeallocate(data_);
393  }
394  data_ = rhs.data_;
395  datasize_ = rhs.datasize_;
396  contiguous_ = rhs.contiguous_;
397  meta_ = rhs.meta_;
398  hal_ = rhs.hal_;
399  dev_ = rhs.dev_;
400  rhs.hal_ = nullptr; // This disables destruction of rhs.data_
401  return *this;
402  }
403 
404  void To(Device dev)
405  {
406  if (dev_ == dev) {
407  return;
408  }
409  if (dev_ == Device::NONE || dev == Device::NONE) {
410  throw std::runtime_error(ECVL_ERROR_MSG "Source or dest device is NONE");
411  }
412 
413  if (dev_ == Device::CPU) { // Move from CPU to other device
414  auto dst_hal_ = HardwareAbstractionLayer::Factory(dev);
415  dst_hal_->FromCpu(*this);
416  }
417  else if (dev == Device::CPU) { // Move from other device to CPU
418  hal_->ToCpu(*this);
419  }
420  else {
421  throw std::runtime_error(ECVL_ERROR_MSG "Source or dest device must be CPU");
422  }
423  }
424 
440  void Create(const std::vector<int>& dims, DataType elemtype, std::string channels, ColorType colortype,
441  const std::vector<float>& spacings = std::vector<float>(), Device dev = Device::CPU);
442 
448  {
449  if (hal_) {
450  hal_->MemDeallocate(data_);
451  }
452  }
453 
455  bool IsEmpty() const { return data_ == nullptr; }
456 
462  bool IsOwner() const { return hal_->IsOwner(); }
463 
465  int Channels() const
466  {
467  size_t c = channels_.find('c');
468  if (c != std::string::npos) {
469  return dims_[c];
470  }
471  c = channels_.find('z');
472  if (c != std::string::npos) {
473  return dims_[c];
474  }
475  c = channels_.find('o');
476  if (c != std::string::npos) {
477  return dims_[c];
478  }
479  return 0;
480  }
481 
483  int Width() const
484  {
485  size_t x = channels_.find('x');
486  if (x != std::string::npos) {
487  return dims_[x];
488  }
489  return 0;
490  }
491 
493  int Height() const
494  {
495  size_t y = channels_.find('y');
496  if (y != std::string::npos) {
497  return dims_[y];
498  }
499  return 0;
500  }
501 
503  uint8_t* Ptr(const std::vector<int>& coords)
504  {
505  assert(coords.size() == strides_.size());
506  return std::inner_product(std::begin(coords), std::end(coords), std::begin(strides_), data_);
507  }
509  const uint8_t* Ptr(const std::vector<int>& coords) const
510  {
511  assert(coords.size() == strides_.size());
512  return std::inner_product(std::begin(coords), std::end(coords), std::begin(strides_), data_);
513  }
514 
516  void Neg()
517  {
518  hal_->Neg(*this, *this, elemtype_, false);
519  }
520 
522  template<typename T>
523  void Add(const T& rhs, bool saturate = true)
524  {
525  hal_->Add(*this, rhs, *this, elemtype_, saturate);
526  }
527 
529  template<typename T>
530  void Sub(const T& rhs, bool saturate = true)
531  {
532  hal_->Sub(*this, rhs, *this, elemtype_, saturate);
533  }
534 
536  template<typename T>
537  void Mul(const T& rhs, bool saturate = true)
538  {
539  hal_->Mul(*this, rhs, *this, elemtype_, saturate);
540  }
541 
543  template<typename T>
544  void Div(const T& rhs, bool saturate = true)
545  {
546  hal_->Div(*this, rhs, *this, elemtype_, saturate);
547  }
548 
550  template<typename T>
551  void SetTo(T value)
552  {
553  hal_->SetTo(*this, value);
554  }
555 
557  void ConvertTo(DataType dtype, bool saturate = true)
558  {
559  hal_->ConvertTo(*this, *this, dtype, saturate);
560  }
561 
562  Image operator-() const;
563 
564  Image& operator+=(const Image& rhs);
565 
566  Image& operator-=(const Image& rhs);
567 
568  Image& operator*=(const Image& rhs);
569 
570  Image& operator/=(const Image& rhs);
571 
572  friend Image operator+(Image lhs, const Image& rhs);
573 
574  friend Image operator-(Image lhs, const Image& rhs);
575 
576  friend Image operator*(Image lhs, const Image& rhs);
577 
578  friend Image operator/(Image lhs, const Image& rhs);
579 };
580 
581 template <typename ViewType>
582 static void CropViewInternal(ViewType& view, const std::vector<int>& start, const std::vector<int>& size)
583 {
584  std::vector<int> new_dims;
585  int ssize = vsize(size);
586  for (int i = 0; i < ssize; ++i) {
587  if (start[i] < 0 || start[i] >= view.dims_[i])
588  throw std::runtime_error("Start of crop outside image limits");
589  new_dims.push_back(view.dims_[i] - start[i]);
590  if (size[i] > new_dims[i]) {
591  throw std::runtime_error("Crop outside image limits");
592  }
593  if (size[i] >= 0) {
594  new_dims[i] = size[i];
595  }
596  }
597 
598  // Check if image has a color dimension
599  auto cpos = view.channels_.find('c');
600  if (cpos != std::string::npos) {
601  // If we are cropping the color channel, we fix the color information
602  if (new_dims[cpos] != view.dims_[cpos]) {
603  if (new_dims[cpos] == 1) {
604  view.colortype_ = ColorType::GRAY;
605  }
606  else {
607  view.channels_[cpos] = 'o';
608  view.colortype_ = ColorType::none;
609  }
610  }
611  }
612 
613  view.data_ = view.Ptr(start);
614 
615  if (view.contiguous_) {
616  for (int i = 0; i < view.dims_.size() - 1; ++i) {
617  if (new_dims[i] != view.dims_[i]) {
618  view.contiguous_ = false;
619  }
620  }
621  }
622  if (view.contiguous_) {
623  view.datasize_ = std::accumulate(std::begin(new_dims), std::end(new_dims), size_t(view.elemsize_), std::multiplies<size_t>());
624  }
625  else {
626  view.datasize_ = 0; // This is set to zero, because when the View is not contiguous, it's useless to relay on this information
627  }
628 
629  view.dims_ = std::move(new_dims);
630 }
631 
632 #include "iterators_impl.inc.h"
633 template <DataType DT>
634 class View : public Image
635 {
636 public:
638 
639  View() {}
640 
641  View(Image& img)
642  {
643  if (DT != img.elemtype_)
644  throw std::runtime_error("View type is different from Image type");
645  elemtype_ = img.elemtype_;
646  elemsize_ = img.elemsize_;
647  dims_ = img.dims_;
648  spacings_ = img.spacings_;
649  strides_ = img.strides_;
650  channels_ = img.channels_;
651  colortype_ = img.colortype_;
652  data_ = img.data_;
653  datasize_ = img.datasize_;
654  contiguous_ = img.contiguous_;
655  meta_ = img.meta_;
656  hal_ = HardwareAbstractionLayer::Factory(img.dev_, true);
657  dev_ = img.dev_;
658  }
659 
660  View(Image& img, const std::vector<int>& start, const std::vector<int>& size) : View(img)
661  {
662  CropViewInternal(*this, start, size);
663  }
664 
665  basetype& operator()(const std::vector<int>& coords)
666  {
667  return *reinterpret_cast<basetype*>(Ptr(coords));
668  }
669 
670  void Create(std::vector<int> dims, std::string channels, ColorType colortype, uint8_t* ptr,
671  const std::vector<float>& spacings = std::vector<float>(), Device dev = Device::CPU)
672  {
673  elemtype_ = DT;
675  dims_ = std::move(dims);
676  spacings_ = spacings;
677  channels_ = std::move(channels);
678  colortype_ = colortype;
679 
682 
683  data_ = ptr;
684  hal_ = HardwareAbstractionLayer::Factory(dev, true);
685  dev_ = dev;
686  return;
687  }
688 
691 };
692 
693 template <DataType DT>
694 class ConstView : public Image
695 {
696 public:
698 
700 
701  ConstView(const Image& img)
702  {
703  elemtype_ = img.elemtype_;
704  elemsize_ = img.elemsize_;
705  dims_ = img.dims_;
706  spacings_ = img.spacings_;
707  strides_ = img.strides_;
708  channels_ = img.channels_;
709  colortype_ = img.colortype_;
710  data_ = img.data_;
711  datasize_ = img.datasize_;
712  contiguous_ = img.contiguous_;
713  meta_ = img.meta_;
714  hal_ = HardwareAbstractionLayer::Factory(img.dev_, true);
715  dev_ = img.dev_;
716  }
717 
718  ConstView(const Image& img, const std::vector<int>& start, const std::vector<int>& size) : ConstView(img)
719  {
720  CropViewInternal(*this, start, size);
721  }
722 
723  const basetype& operator()(const std::vector<int>& coords)
724  {
725  return *reinterpret_cast<const basetype*>(Ptr(coords));
726  }
727 
730 };
731 
732 template <DataType DT>
733 class ContiguousView : public Image
734 {
735 public:
737 
739 
741  {
742  elemtype_ = img.elemtype_;
743  elemsize_ = img.elemsize_;
744  dims_ = img.dims_;
745  spacings_ = img.spacings_;
746  strides_ = img.strides_;
747  channels_ = img.channels_;
748  colortype_ = img.colortype_;
749  data_ = img.data_;
750  datasize_ = img.datasize_;
751  contiguous_ = img.contiguous_;
752  meta_ = img.meta_;
753  hal_ = HardwareAbstractionLayer::Factory(img.dev_, true);
754  dev_ = img.dev_;
755  }
756 
757  basetype& operator()(const std::vector<int>& coords)
758  {
759  return *reinterpret_cast<basetype*>(Ptr(coords));
760  }
761 
764 };
765 
766 template <DataType DT>
768 {
769 public:
771 
773 
775  {
776  elemtype_ = img.elemtype_;
777  elemsize_ = img.elemsize_;
778  dims_ = img.dims_;
779  spacings_ = img.spacings_;
780  strides_ = img.strides_;
781  channels_ = img.channels_;
782  colortype_ = img.colortype_;
783  data_ = img.data_;
784  datasize_ = img.datasize_;
785  contiguous_ = img.contiguous_;
786  meta_ = img.meta_;
787  hal_ = HardwareAbstractionLayer::Factory(img.dev_, true);
788  dev_ = img.dev_;
789  }
790 
791  const basetype& operator()(const std::vector<int>& coords)
792  {
793  return *reinterpret_cast<const basetype*>(Ptr(coords));
794  }
795 
798 };
799 
800 template <DataType DT>
801 class ContiguousViewXYC : public Image
802 {
803 public:
805 
807  {
808  if (img.channels_ != "xyc")
809  throw std::runtime_error("ContiguousView2D can be built only from \"xyc\" images");
810  if (!img.contiguous_)
811  throw std::runtime_error("ContiguousView2D can be built only from images with contiguous data");
812  elemtype_ = img.elemtype_;
813  elemsize_ = img.elemsize_;
814  dims_ = img.dims_;
815  spacings_ = img.spacings_;
816  strides_ = img.strides_;
817  channels_ = img.channels_;
818  colortype_ = img.colortype_;
819  data_ = img.data_;
820  datasize_ = img.datasize_;
821  contiguous_ = img.contiguous_;
822  meta_ = img.meta_;
823  hal_ = HardwareAbstractionLayer::Factory(img.dev_, true);
824  dev_ = img.dev_;
825  }
826 
827  int width() const { return dims_[0]; }
828  int height() const { return dims_[1]; }
829  int channels() const { return dims_[2]; }
830 
831  basetype& operator()(int x, int y, int c)
832  {
833  return *reinterpret_cast<basetype*>(data_ + c * strides_[2] + y * strides_[1] + x * strides_[0]);
834  }
835 
838 };
839 
840 template <DataType DT>
842 {
843 public:
845 
847  {
848  if (img.channels_ != "xyc")
849  throw std::runtime_error("ContiguousView2D can be built only from \"xyc\" images");
850  if (!img.contiguous_)
851  throw std::runtime_error("ContiguousView2D can be built only from images with contiguous data");
852  elemtype_ = img.elemtype_;
853  elemsize_ = img.elemsize_;
854  dims_ = img.dims_;
855  spacings_ = img.spacings_;
856  strides_ = img.strides_;
857  channels_ = img.channels_;
858  colortype_ = img.colortype_;
859  data_ = img.data_;
860  datasize_ = img.datasize_;
861  contiguous_ = img.contiguous_;
862  meta_ = img.meta_;
863  hal_ = HardwareAbstractionLayer::Factory(img.dev_, true);
864  dev_ = img.dev_;
865  }
866 
867  int width() const { return dims_[0]; }
868  int height() const { return dims_[1]; }
869  int channels() const { return dims_[2]; }
870 
871  const basetype& operator()(int x, int y, int c) const
872  {
873  return *reinterpret_cast<basetype*>(data_ + c * strides_[2] + y * strides_[1] + x * strides_[0]);
874  }
875 
878 };
879 
893 void RearrangeChannels(const Image& src, Image& dst, const std::string& channels);
894 
905 void RearrangeChannels(const Image& src, Image& dst, const std::string& channels, DataType new_type);
906 
942 void CopyImage(const Image& src, Image& dst, DataType new_type = DataType::none);
943 
953 void CopyImage(const Image& src, Image& dst, DataType new_type, const std::string& channels);
954 
968 void ShallowCopyImage(const Image& src, Image& dst);
969 
979 void ConvertTo(const Image& src, Image& dst, DataType dtype, bool saturate = true);
980 
981 
985 } // namespace ecvl
986 
987 #endif // !ECVL_IMAGE_H_
virtual ~MetaData()
Definition: image.h:43
ContiguousIterator< basetype > End()
Definition: image.h:837
Image class.
Definition: image.h:72
ConstContiguousIterator< T > ContiguousEnd() const
Contiguous const End Iterator.
Definition: image.h:257
ContiguousIterator< basetype > Begin()
Definition: image.h:762
Image & operator/=(const Image &rhs)
ConstContiguousView(const Image &img)
Definition: image.h:774
typename TypeInfo< DT >::basetype basetype
Definition: image.h:637
int Width() const
Returns the width of Image.
Definition: image.h:483
uint8_t * data_
Pointer to Image data.
Definition: image.h:168
void Neg()
In-place negation.
Definition: image.h:516
void Create(std::vector< int > dims, std::string channels, ColorType colortype, uint8_t *ptr, const std::vector< float > &spacings=std::vector< float >(), Device dev=Device::CPU)
Definition: image.h:670
ConstView(const Image &img, const std::vector< int > &start, const std::vector< int > &size)
Definition: image.h:718
basetype & operator()(const std::vector< int > &coords)
Definition: image.h:665
HardwareAbstractionLayer * hal_
Pointer to the HardwareAbstractionLayer employed by the Image.
Definition: image.h:179
basetype & operator()(int x, int y, int c)
Definition: image.h:831
std::string channels_
String which describes how Image planes are organized.
Definition: image.h:130
size_t datasize_
Size of Image data in bytes.
Definition: image.h:175
Image & operator *=(const Image &rhs)
const basetype & operator()(const std::vector< int > &coords)
Definition: image.h:723
friend Image operator+(Image lhs, const Image &rhs)
ContiguousViewXYC(Image &img)
Definition: image.h:806
int vsize(const std::vector< T > &v)
Definition: image.h:34
void SetDefaultStrides()
Sets default strides for contiguous memory layouts.
Definition: image.h:85
typename TypeInfo< DT >::basetype basetype
Definition: image.h:804
const basetype & operator()(const std::vector< int > &coords)
Definition: image.h:791
DataType
DataType is an enum class which defines data types allowed for images.
Definition: datatype.h:43
DataType elemtype_
Type of Image pixels, must be one of the values available in DataType.
Definition: image.h:120
ColorType
Enum class representing the ECVL supported color spaces.
Definition: image.h:50
basetype & operator()(const std::vector< int > &coords)
Definition: image.h:757
ColorType colortype_
Image ColorType.
Definition: image.h:153
ConstContiguousIterator< T > ContiguousBegin() const
Contiguous const Begin Iterator.
Definition: image.h:250
Image & operator=(const Image &rhs)
Definition: image.h:370
View(Image &img)
Definition: image.h:641
ContiguousView(Image &img)
Definition: image.h:740
Iterator< basetype > End()
Definition: image.h:690
size_t GetDefaultDatasize()
Gets the default datasize for contiguous images.
Definition: image.h:101
int Height() const
Returns the height of Image.
Definition: image.h:493
ContiguousIterator< basetype > Begin()
Definition: image.h:836
std::vector< int > strides_
Vector of Image strides.
Definition: image.h:125
Image(const std::vector< int > &dims, DataType elemtype, std::string channels, ColorType colortype, const std::vector< float > &spacings=std::vector< float >(), Device dev=Device::CPU)
Initializing constructor.
Definition: image.h:284
uint8_t * Ptr(const std::vector< int > &coords)
Returns a non-const pointer to data at given coordinates.
Definition: image.h:503
Image & operator+=(const Image &rhs)
ConstContiguousViewXYC(const Image &img)
Definition: image.h:846
virtual bool Query(const std::string &name, std::string &value) const =0
Image & operator=(Image &&rhs)
Definition: image.h:380
uint8_t elemsize_
Size (in bytes) of Image pixels.
Definition: image.h:122
ContiguousIterator< T > ContiguousBegin()
Contiguous non-const Begin Iterator.
Definition: image.h:233
ConstContiguousIterator< basetype > End()
Definition: image.h:797
Image(const Image &img)
Copy constructor.
Definition: image.h:312
ConstContiguousIterator< basetype > End()
Definition: image.h:877
void ConvertTo(DataType dtype, bool saturate=true)
Convert Image to another DataType.
Definition: image.h:557
View(Image &img, const std::vector< int > &start, const std::vector< int > &size)
Definition: image.h:660
void SetTo(T value)
Set Image value to rhs.
Definition: image.h:551
bool contiguous_
Whether the image is stored contiguously or not in memory.
Definition: image.h:176
void ShallowCopyImage(const Image &src, Image &dst)
Performs a shallow copy of the source Image into the destination.
typename TypeInfo< DT >::basetype basetype
Definition: image.h:770
int channels() const
Definition: image.h:829
int height() const
Definition: image.h:828
void basetype
Definition: datatype.h:61
ConstView(const Image &img)
Definition: image.h:701
friend void swap(Image &lhs, Image &rhs)
Definition: image.h:352
ConstContiguousIterator< basetype > Begin()
Definition: image.h:796
void Create(const std::vector< int > &dims, DataType elemtype, std::string channels, ColorType colortype, const std::vector< float > &spacings=std::vector< float >(), Device dev=Device::CPU)
Allocates new contiguous data if needed.
bool IsOwner() const
To check whether the Image is owner of the data.
Definition: image.h:462
std::vector< int > dims_
Definition: image.h:123
void Div(const T &rhs, bool saturate=true)
In-place division.
Definition: image.h:544
friend Image operator *(Image lhs, const Image &rhs)
#define ECVL_ERROR_MSG
void RearrangeChannels(const Image &src, Image &dst, const std::string &channels)
Changes the order of the Image dimensions.
ConstContiguousIterator< basetype > Begin()
Definition: image.h:876
Iterator< T > Begin()
Generic non-const Begin Iterator.
Definition: image.h:199
ContiguousIterator< T > ContiguousEnd()
Contiguous non-const End Iterator.
Definition: image.h:241
void Mul(const T &rhs, bool saturate=true)
In-place multiplication.
Definition: image.h:537
friend class HardwareAbstractionLayer
Definition: image.h:117
ContiguousIterator< basetype > End()
Definition: image.h:763
typename TypeInfo< DT >::basetype basetype
Definition: image.h:736
friend Image operator/(Image lhs, const Image &rhs)
const basetype & operator()(int x, int y, int c) const
Definition: image.h:871
Image()
Default constructor.
Definition: image.h:263
const uint8_t * Ptr(const std::vector< int > &coords) const
Returns a const pointer to data at given coordinates.
Definition: image.h:509
int width() const
Definition: image.h:827
Device dev_
Identifier for the device on which the image data is.
Definition: image.h:187
Image(Image &&img)
Move constructor.
Definition: image.h:334
bool IsEmpty() const
To check whether the Image contains data or not, regardless of the owning status.
Definition: image.h:455
void ConvertTo(const Image &src, Image &dst, DataType dtype, bool saturate=true)
Convert Image to another DataType.
void To(Device dev)
Definition: image.h:404
typename TypeInfo< DT >::basetype basetype
Definition: image.h:844
void CopyImage(const Image &src, Image &dst, DataType new_type=DataType::none)
Copies the source Image into the destination Image.
int Channels() const
Returns the number of channels.
Definition: image.h:465
ConstIterator< basetype > End()
Definition: image.h:729
uint8_t DataTypeSize(DataType dt)
Provides the size in bytes of a given DataType.
Iterator< basetype > Begin()
Definition: image.h:689
Image operator-() const
void SetDefaultDatasize()
Sets the default datasize for contiguous images.
Definition: image.h:112
typename TypeInfo< DT >::basetype basetype
Definition: image.h:697
ConstIterator< T > Begin() const
Generic const Begin Iterator.
Definition: image.h:216
MetaData * meta_
Pointer to Image MetaData.
Definition: image.h:178
ConstIterator< T > End() const
Generic const End Iterator.
Definition: image.h:224
void Sub(const T &rhs, bool saturate=true)
In-place subtraction.
Definition: image.h:530
~Image()
Destructor.
Definition: image.h:447
void Add(const T &rhs, bool saturate=true)
In-place addition.
Definition: image.h:523
View()
Definition: image.h:639
ConstIterator< basetype > Begin()
Definition: image.h:728
Iterator< T > End()
Generic non-const End Iterator.
Definition: image.h:207
Image & operator-=(const Image &rhs)
std::vector< float > spacings_
Space between pixels/voxels.
Definition: image.h:163