22 #include <opencv2/core.hpp> 35 int vsize(
const std::vector<T>& v)
37 return static_cast<int>(v.size());
57 template <DataType DT>
60 template <DataType DT>
84 for (
int i = 0; i < dsize - 1; ++i) {
97 return std::accumulate(std::begin(
dims_), std::end(
dims_),
size_t(
elemsize_), std::multiplies<size_t>());
172 std::unordered_map<std::string, MetaData>
meta_;
279 const std::vector<float>& spacings = std::vector<float>(), Device dev = Device::CPU,
const std::unordered_map<std::string, MetaData>& meta = {}) :
291 hal_{ HardwareAbstractionLayer::Factory(dev) },
295 throw std::runtime_error(
"Number of dimensions must match number of channels.");
321 hal_->Copy(img, *
this);
376 assert(
this != &rhs);
403 if (
dev_ == Device::NONE || dev == Device::NONE) {
404 throw std::runtime_error(
ECVL_ERROR_MSG "Source or dest device is NONE");
407 if (
dev_ == Device::CPU) {
408 auto dst_hal_ = HardwareAbstractionLayer::Factory(dev);
409 dst_hal_->FromCpu(*
this);
411 else if (dev == Device::CPU) {
415 throw std::runtime_error(
ECVL_ERROR_MSG "Source or dest device must be CPU");
435 const std::vector<float>& spacings = std::vector<float>(), Device dev = Device::CPU,
const std::unordered_map<std::string, MetaData>& meta = {});
462 if (c != std::string::npos) {
466 if (c != std::string::npos) {
470 if (c != std::string::npos) {
480 if (x != std::string::npos) {
490 if (y != std::string::npos) {
497 uint8_t*
Ptr(
const std::vector<int>& coords)
499 assert(coords.size() ==
strides_.size());
500 return std::inner_product(std::begin(coords), std::end(coords), std::begin(
strides_),
data_);
503 const uint8_t*
Ptr(
const std::vector<int>& coords)
const 505 assert(coords.size() ==
strides_.size());
506 return std::inner_product(std::begin(coords), std::end(coords), std::begin(
strides_),
data_);
517 void Add(
const T& rhs,
bool saturate =
true)
524 void Sub(
const T& rhs,
bool saturate =
true)
531 void Mul(
const T& rhs,
bool saturate =
true)
538 void Div(
const T& rhs,
bool saturate =
true)
547 hal_->SetTo(*
this, value);
553 hal_->ConvertTo(*
this, *
this, dtype, saturate);
559 return this->meta_.at(key);
565 return this->meta_.insert_or_assign(key,
MetaData(value, 0)).second;
587 template <
typename ViewType>
588 static void CropViewInternal(ViewType& view,
const std::vector<int>& start,
const std::vector<int>& size)
590 std::vector<int> new_dims;
591 int ssize =
vsize(size);
592 for (
int i = 0; i < ssize; ++i) {
593 if (start[i] < 0 || start[i] >= view.dims_[i])
594 throw std::runtime_error(
"Start of crop outside image limits");
595 new_dims.push_back(view.dims_[i] - start[i]);
596 if (size[i] > new_dims[i]) {
597 throw std::runtime_error(
"Crop outside image limits");
600 new_dims[i] = size[i];
605 auto cpos = view.channels_.find(
'c');
606 if (cpos != std::string::npos) {
608 if (new_dims[cpos] != view.dims_[cpos]) {
609 if (new_dims[cpos] == 1) {
613 view.channels_[cpos] =
'o';
619 view.data_ = view.Ptr(start);
621 if (view.contiguous_) {
622 for (
int i = 0; i < view.dims_.size() - 1; ++i) {
623 if (new_dims[i] != view.dims_[i]) {
624 view.contiguous_ =
false;
628 if (view.contiguous_) {
629 view.datasize_ = std::accumulate(std::begin(new_dims), std::end(new_dims),
size_t(view.elemsize_), std::multiplies<size_t>());
635 view.dims_ = std::move(new_dims);
639 template <DataType DT>
640 class View :
public Image
650 throw std::runtime_error(
"View type is different from Image type");
662 hal_ = HardwareAbstractionLayer::Factory(img.
dev_,
true);
666 View(
Image& img,
const std::vector<int>& start,
const std::vector<int>& size) :
View(img)
668 CropViewInternal(*
this, start, size);
673 return *reinterpret_cast<basetype*>(
Ptr(coords));
676 void Create(std::vector<int> dims, std::string channels,
ColorType colortype, uint8_t* ptr,
677 const std::vector<float>& spacings = std::vector<float>(), Device dev = Device::CPU,
const std::unordered_map<std::string, MetaData>& meta = {})
681 dims_ = std::move(dims);
690 hal_ = HardwareAbstractionLayer::Factory(dev,
true);
700 template <DataType DT>
701 class ConstView :
public Image
721 hal_ = HardwareAbstractionLayer::Factory(img.
dev_,
true);
727 CropViewInternal(*
this, start, size);
732 return *reinterpret_cast<const basetype*>(
Ptr(coords));
739 template <DataType DT>
760 hal_ = HardwareAbstractionLayer::Factory(img.
dev_,
true);
766 return *reinterpret_cast<basetype*>(
Ptr(coords));
773 template <DataType DT>
794 hal_ = HardwareAbstractionLayer::Factory(img.
dev_,
true);
800 return *reinterpret_cast<const basetype*>(
Ptr(coords));
807 template <DataType DT>
816 throw std::runtime_error(
"ContiguousView2D can be built only from \"xyc\" images");
818 throw std::runtime_error(
"ContiguousView2D can be built only from images with contiguous data");
830 hal_ = HardwareAbstractionLayer::Factory(img.
dev_,
true);
847 template <DataType DT>
856 throw std::runtime_error(
"ContiguousView2D can be built only from \"xyc\" images");
858 throw std::runtime_error(
"ContiguousView2D can be built only from images with contiguous data");
870 hal_ = HardwareAbstractionLayer::Factory(img.
dev_,
true);
900 void RearrangeChannels(
const Image& src, Image& dst,
const std::string& channels);
960 void CopyImage(
const Image& src, Image& dst,
DataType new_type,
const std::string& channels);
986 void ConvertTo(
const Image& src, Image& dst,
DataType dtype,
bool saturate =
true);
994 #endif // !ECVL_IMAGE_H_
ContiguousIterator< basetype > End()
ConstContiguousIterator< T > ContiguousEnd() const
Contiguous const End Iterator.
ContiguousIterator< basetype > Begin()
Image & operator/=(const Image &rhs)
ConstContiguousView(const Image &img)
typename TypeInfo< DT >::basetype basetype
int Width() const
Returns the width of Image.
uint8_t * data_
Pointer to Image data.
void Neg()
In-place negation.
ConstView(const Image &img, const std::vector< int > &start, const std::vector< int > &size)
basetype & operator()(const std::vector< int > &coords)
HardwareAbstractionLayer * hal_
Pointer to the HardwareAbstractionLayer employed by the Image.
basetype & operator()(int x, int y, int c)
std::string channels_
String which describes how Image planes are organized.
size_t datasize_
Size of Image data in bytes.
Image & operator *=(const Image &rhs)
const basetype & operator()(const std::vector< int > &coords)
friend Image operator+(Image lhs, const Image &rhs)
ContiguousViewXYC(Image &img)
int vsize(const std::vector< T > &v)
void SetDefaultStrides()
Sets default strides for contiguous memory layouts.
typename TypeInfo< DT >::basetype basetype
const basetype & operator()(const std::vector< int > &coords)
DataType
DataType is an enum class which defines data types allowed for images.
DataType elemtype_
Type of Image pixels, must be one of the values available in DataType.
ColorType
Enum class representing the ECVL supported color spaces.
basetype & operator()(const std::vector< int > &coords)
ColorType colortype_
Image ColorType.
ConstContiguousIterator< T > ContiguousBegin() const
Contiguous const Begin Iterator.
Image & operator=(const Image &rhs)
ContiguousView(Image &img)
Iterator< basetype > End()
size_t GetDefaultDatasize()
Gets the default datasize for contiguous images.
int Height() const
Returns the height of Image.
ContiguousIterator< basetype > Begin()
std::vector< int > strides_
Vector of Image strides.
uint8_t * Ptr(const std::vector< int > &coords)
Returns a non-const pointer to data at given coordinates.
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, const std::unordered_map< std::string, MetaData > &meta={})
Image & operator+=(const Image &rhs)
ConstContiguousViewXYC(const Image &img)
Image & operator=(Image &&rhs)
uint8_t elemsize_
Size (in bytes) of Image pixels.
ContiguousIterator< T > ContiguousBegin()
Contiguous non-const Begin Iterator.
ConstContiguousIterator< basetype > End()
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, const std::unordered_map< std::string, MetaData > &meta={})
Allocates new contiguous data if needed.
Image(const Image &img)
Copy constructor.
ConstContiguousIterator< basetype > End()
void ConvertTo(DataType dtype, bool saturate=true)
Convert Image to another DataType.
View(Image &img, const std::vector< int > &start, const std::vector< int > &size)
void SetTo(T value)
Set Image value to rhs.
bool contiguous_
Whether the image is stored contiguously or not in memory.
std::unordered_map< std::string, MetaData > meta_
Pointer to Image MetaData.
void ShallowCopyImage(const Image &src, Image &dst)
Performs a shallow copy of the source Image into the destination.
typename TypeInfo< DT >::basetype basetype
ConstView(const Image &img)
friend void swap(Image &lhs, Image &rhs)
ConstContiguousIterator< basetype > Begin()
bool IsOwner() const
To check whether the Image is owner of the data.
void Div(const T &rhs, bool saturate=true)
In-place division.
friend Image operator *(Image lhs, const Image &rhs)
void RearrangeChannels(const Image &src, Image &dst, const std::string &channels)
Changes the order of the Image dimensions.
ConstContiguousIterator< basetype > Begin()
Iterator< T > Begin()
Generic non-const Begin Iterator.
ContiguousIterator< T > ContiguousEnd()
Contiguous non-const End Iterator.
void Mul(const T &rhs, bool saturate=true)
In-place multiplication.
friend class HardwareAbstractionLayer
ContiguousIterator< basetype > End()
typename TypeInfo< DT >::basetype basetype
bool SetMeta(const std::string &key, const std::any &value)
Update the metadata value if the key already exists (return false) or insert the pair if not found (r...
friend Image operator/(Image lhs, const Image &rhs)
std::experimental::any any
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, const std::unordered_map< std::string, MetaData > &meta={})
Initializing constructor.
const basetype & operator()(int x, int y, int c) const
Image()
Default constructor.
const uint8_t * Ptr(const std::vector< int > &coords) const
Returns a const pointer to data at given coordinates.
Device dev_
Identifier for the device on which the image data is.
Image(Image &&img)
Move constructor.
bool IsEmpty() const
To check whether the Image contains data or not, regardless of the owning status.
void ConvertTo(const Image &src, Image &dst, DataType dtype, bool saturate=true)
Convert Image to another DataType.
typename TypeInfo< DT >::basetype basetype
void CopyImage(const Image &src, Image &dst, DataType new_type=DataType::none)
Copies the source Image into the destination Image.
MetaData GetMeta(const std::string &key) const
Return the metadata identified by key.
int Channels() const
Returns the number of channels.
ConstIterator< basetype > End()
uint8_t DataTypeSize(DataType dt)
Provides the size in bytes of a given DataType.
Iterator< basetype > Begin()
void SetDefaultDatasize()
Sets the default datasize for contiguous images.
typename TypeInfo< DT >::basetype basetype
ConstIterator< T > Begin() const
Generic const Begin Iterator.
ConstIterator< T > End() const
Generic const End Iterator.
void Sub(const T &rhs, bool saturate=true)
In-place subtraction.
void Add(const T &rhs, bool saturate=true)
In-place addition.
ConstIterator< basetype > Begin()
Iterator< T > End()
Generic non-const End Iterator.
Image & operator-=(const Image &rhs)
std::vector< float > spacings_
Space between pixels/voxels.