iVS3D v2.0.0
Loading...
Searching...
No Matches
NN::Tensor Class Reference

A Tensor represents a N-dimensional array containing elements of the same type. Can be used as input and output for inference. More...

#include <Tensor.h>

Public Member Functions

template<typename T >
tl::expected< std::vector< T >, NeuralErrortoVector () const
 Create a vector containing the data from the Tensor.
 
tl::expected< cv::Mat, NeuralErrortoCvMat () const
 Create a cv::Mat from a Tensor. In case of 2/3 dimensions this will convert back to CVs HWC layout. Returns an error for dimensions other than 2 or 3.
 
const Shapeshape () const
 Readonly access to the shape of the tensor. Valid tensors ensure the shape is static, so no dimension is -1.
 
std::string toString () const
 Create a human-readable string representation containing the Tensors shape and data type.
 
tl::expected< void, NeuralErrorreshape (const Shape &newShape)
 Reshape will interprete the data elements contained in the Tensor as a different shape. This does not move any elements!
 
int64_t numElements () const
 Returns the number of elements contained in the Tensor.
 
bool empty () const
 Check if the tensor is empty, so to say it contains no elements.
 
TensorType dtype () const
 Check the data type of the Tensor. This is deduced from the data type of the contained elements.
 
template<typename Op >
tl::expected< Tensor, NeuralErrorreduce (const Op &op, uint64_t axis) const
 Reduce the Tensor along a given axis by applying an accumulative operation.
 
template<typename Op >
tl::expected< Tensor, NeuralErrorreduceWithIndex (const Op &op, uint64_t axis) const
 Reduce the Tensor along a given axis by applying an accumulative operation. The dimension in the rduced axis will be 1 after this.
 
template<typename Func >
tl::expected< Tensor, NeuralErrormap (Func &&f) const
 Map each element of the Tensor to a new value by applying a given function element-wise. This can be used to change the datatype as well.
 
template<typename Func >
tl::expected< Tensor, NeuralErrormap (Func &&func, int axis) const
 Map each element of the Tensor to an array of new values by applying a given function element-wise. This adds a new dimension in the given axis.
 
tl::expected< void, NeuralErrorsqueeze ()
 Squeeze the Tensor by removing dimensions of size 1. This operation is performed inplace.
 
tl::expected< void, NeuralErrorsqueeze (int64_t axis)
 Squeeze the Tensor by removing a specific dimension of size 1.
 
tl::expected< void, NeuralErrorunsqueeze (int64_t axis)
 Add a new dimension of size 1 at the specified axis.
 

Static Public Member Functions

static tl::expected< Tensor, NeuralErrorfromCvMat (const cv::Mat &mat)
 Create a new Tensor object from a cv::Mat. This will convert from CVs HWC layout to ONNX standard layout [N]CHW. In this case the N -dimsension is NOT created as it would be 1!
 
static tl::expected< Tensor, NeuralErrorfromCvMat (const cv::Mat &mat, const Shape &shape, float scale=1.0f, std::vector< float > mean={}, std::vector< float > std={})
 Create a new Tensor object from a cv::Mat with a specific shape, optional scaling, and per-channel mean-subtraction.
 
static tl::expected< Tensor, NeuralErrorfromCvMats (const std::vector< cv::Mat > &mats)
 Create a new Tensor object from a vector of cv::Mat objects. The cv::Mat objects must have the same size and type.
 
static tl::expected< Tensor, NeuralErrorfromCvMats (const std::vector< cv::Mat > &mats, const Shape &shape, float scale=1.0f, std::vector< float > mean={}, std::vector< float > std={})
 Create a new Tensor object from a vector of cv::Mat objects with a specific shape, optional scaling, and per-channel mean-subtraction.
 
template<typename T >
static tl::expected< Tensor, NeuralErrorfromData (const std::vector< T > &data, const Shape &shape)
 Create a new Tensor object from a given data vector and shape. The number of elements in the vector must match shapeNumElements(shape).
 
template<typename T >
static tl::expected< Tensor, NeuralErrorfromData (std::vector< T > &&data, const Shape &shape)
 Create a new Tensor object from a given data vector and shape. The number of elements in the vector must match shapeNumElements(shape).
 

Static Private Member Functions

template<typename T , int CV_TYPE>
static tl::expected< Tensor, NeuralErrorfromCvMatsTyped (const std::vector< cv::Mat > &mats)
 Create a new Tensor object from a vector of cv::Mat objects with a specific type.
 
static cv::Mat preprocessCvMat (const cv::Mat &mat, const Shape &shape, float scale)
 Preprocess a cv::Mat to match the given shape by resizing, color conversion from BGR to RGB, and scaling.
 
static cv::Mat preprocessCvMat (const cv::Mat &mat, const Shape &shape, float scale, const std::vector< float > &mean, const std::vector< float > &std)
 Preprocess a cv::Mat to match the given shape by resizing, color conversion from BGR to RGB, scaling, and applying mean and std.
 

Detailed Description

A Tensor represents a N-dimensional array containing elements of the same type. Can be used as input and output for inference.

Supported element types are:

  • uint8_t
  • float
  • int64_t
See also
TensorType for the supported types.

Tensors can be created from and converted to cv::Mat or std::vector<T>. The element type is passed as a Template argument or deduced from the cv::Mat::depth property.

Date
May 2025
Author
Dominik Wüst (domin.nosp@m.ik.w.nosp@m.uest@.nosp@m.iosb.nosp@m..frau.nosp@m.nhof.nosp@m.er.de)

Member Function Documentation

◆ dtype()

TensorType NN::Tensor::dtype ( ) const
inline

Check the data type of the Tensor. This is deduced from the data type of the contained elements.

Returns
TensorType

◆ empty()

bool NN::Tensor::empty ( ) const
inline

Check if the tensor is empty, so to say it contains no elements.

Returns
true If the Tensor contains no elements.
false If the Tensor contains one or more element.

◆ fromCvMat() [1/2]

tl::expected< Tensor, NeuralError > NN::Tensor::fromCvMat ( const cv::Mat &  mat)
static

Create a new Tensor object from a cv::Mat. This will convert from CVs HWC layout to ONNX standard layout [N]CHW. In this case the N -dimsension is NOT created as it would be 1!

Parameters
matThe cv::Mat containing the data in HWC layout for the Tensor.
Returns
tl::expected<Tensor, NeuralError> A Tensor in CHW layout or an error object.

◆ fromCvMat() [2/2]

tl::expected< Tensor, NeuralError > NN::Tensor::fromCvMat ( const cv::Mat &  mat,
const Shape shape,
float  scale = 1.0f,
std::vector< float >  mean = {},
std::vector< float >  std = {} 
)
static

Create a new Tensor object from a cv::Mat with a specific shape, optional scaling, and per-channel mean-subtraction.

Parameters
matThe cv::Mat containing the data in HWC layout for the Tensor.
shapeThe desired shape of the Tensor.
scaleThe scale factor to apply to the input data (default: 1.0).
meanThe mean values to subtract from each channel (default: empty vector).
stdThe standard deviation values to divide each channel by (default: empty vector).
Returns
tl::expected<Tensor, NeuralError> A Tensor in CHW layout or an error object.

This function creates a Tensor from a cv::Mat with the specified shape. The shape must be valid, meaning it must have at least two dimensions [...,H,W]. If the Channel dimension is present, it must match the number of channels in the cv::Mat or be -1 (dynamic).

  • If the cv::Mat is grayscale, it will be converted to a single channel Tensor.
  • If the cv::Mat has 3 channels, it will be converted from BGR to RGB.
  • If the cv::Mat has more than 3 channels, it will be treated as a multi-channel Tensor.

The following steps are applied (in this order):

  1. Resize the cv::Mat to match W and H of the shape if necessary.
  2. If input is BGR, convert it to RGB.
  3. The data will be converted to float32 and scaled by the given scale factor.
  4. If a mean vector is provided, it will be subtracted from each channel.
  5. If a std vector is provided, each channel will be divided by the corresponding std value.

The resulting Tensor will be of type float32. Its shape will be squeezed, i.e. leading dimensions of size 1 and dynamic dimensions will be removed.

◆ fromCvMats() [1/2]

tl::expected< Tensor, NeuralError > NN::Tensor::fromCvMats ( const std::vector< cv::Mat > &  mats)
static

Create a new Tensor object from a vector of cv::Mat objects. The cv::Mat objects must have the same size and type.

Parameters
matsThe vector of cv::Mat objects to convert.
Returns
tl::expected<Tensor, NeuralError> A Tensor object containing the stacked cv::Mat data in NCHW layout or an error object.

The function stacks the cv::Mat objects along the first dimension (N) and converts them to a Tensor in NCHW layout. The following requirements must be met:

  • All cv::Mat objects must have the same size (rows, cols, channels) and type.
  • The cv::Mat objects must not be empty.
  • The cv::Mat objects must have a type of either CV_8U or CV_32F.

The resulting Tensor will have a shape of [N,C,H,W], where:

  • N is the number of cv::Mat objects in the input vector.
  • C is the number of channels in the cv::Mat objects.
  • H is the height (rows) of the cv::Mat objects.
  • W is the width (cols) of the cv::Mat objects.

The datatype of the Tensor will be determined by the cv::Mat type.

◆ fromCvMats() [2/2]

tl::expected< Tensor, NeuralError > NN::Tensor::fromCvMats ( const std::vector< cv::Mat > &  mats,
const Shape shape,
float  scale = 1.0f,
std::vector< float >  mean = {},
std::vector< float >  std = {} 
)
static

Create a new Tensor object from a vector of cv::Mat objects with a specific shape, optional scaling, and per-channel mean-subtraction.

Parameters
matsThe vector of cv::Mat objects to convert.
shapeThe desired shape of the Tensor.
scaleThe scale factor to apply to the input data (default: 1.0).
meanThe mean values to subtract from each channel (default: empty vector).
Returns
tl::expected<Tensor, NeuralError> A Tensor object containing the stacked cv::Mat data in NCHW layout or an error object.

This function creates a Tensor from a vector of cv::Mat objects with the specified shape. The shape must match the following requirements:

  • The shape must have four dimensions [N,C,H,W].
  • The first dimension (N) is the number of cv::Mat objects in the input vector.
  • The second dimension (C) is the number of channels in the cv::Mat objects.

If the size of the cv::Mat objects does not match the height and width specified in the shape, they will be resized accordingly. The following steps are applied (in this order):

  1. Resize each cv::Mat to match the height and width specified in the shape.
  2. The cv:Mat is converted from BGR to RGB.
  3. The data will be converted to float32 and scaled by the scale factor.
  4. If a mean vector is provided, it will be subtracted per-channel.
  5. If a std vector is provided, each channel will be divided by the corresponding std value.

◆ fromCvMatsTyped()

template<typename T , int CV_TYPE>
static tl::expected< Tensor, NeuralError > NN::Tensor::fromCvMatsTyped ( const std::vector< cv::Mat > &  mats)
inlinestaticprivate

Create a new Tensor object from a vector of cv::Mat objects with a specific type.

Parameters
matsThe vector of cv::Mat objects to convert.
Template Parameters
TThe datatype of the cv::Mat objects, must be one of the following: uint8_t, float.
CV_TYPEThe OpenCV type of the cv::Mat objects, must be one of the following: CV_8U, CV_32F.
Returns
tl::expected<Tensor, NeuralError> A Tensor object containing the stacked cv::Mat data in NCHW layout or an error object.

◆ fromData() [1/2]

template<typename T >
static tl::expected< Tensor, NeuralError > NN::Tensor::fromData ( const std::vector< T > &  data,
const Shape shape 
)
inlinestatic

Create a new Tensor object from a given data vector and shape. The number of elements in the vector must match shapeNumElements(shape).

Template Parameters
TThe datatype, this must be on of the following: uint8_t, int64_t, float.
Parameters
dataThe data vector. This will be copied!
shapeThe shape of the new Tensor.
Returns
tl::expected<Tensor, NeuralError> A Tensor object containing the data and shape or an error object.

This function creates a Tensor from a vector of data. The data will be copied!

See also
fromData(std::vector<T>&&, const Shape&) for a move version.
reduce.cpp for an example of using this function.

◆ fromData() [2/2]

template<typename T >
static tl::expected< Tensor, NeuralError > NN::Tensor::fromData ( std::vector< T > &&  data,
const Shape shape 
)
inlinestatic

Create a new Tensor object from a given data vector and shape. The number of elements in the vector must match shapeNumElements(shape).

Template Parameters
TThe datatype, this must be on of the following: uint8_t, int64_t, float.
Parameters
dataThe data vector. The new Tensor takes ownership of the data!
shapeThe shape of the new Tensor.
Returns
tl::expected<Tensor, NeuralError> A Tensor object containing the data and shape or an error object.

This function creates a Tensor from a vector of data. The data will be moved into the Tensor! This is useful for performance reasons when you already have the data in a vector and want to avoid copying.

// Create a 2D tensor with float data
Shape shape2d = {3, 4}; // 3x4 tensor (CHW format)
std::vector<float> data2d = {1.0, 2.0, 3.0, 4.0,
5.0, 6.0, 7.0, 8.0,
9.0, 10.0, 11.0, 12.0};
auto tensor2d = Tensor::fromData(std::move(data2d), shape2d);
static tl::expected< Tensor, NeuralError > fromData(const std::vector< T > &data, const Shape &shape)
Create a new Tensor object from a given data vector and shape. The number of elements in the vector m...
Definition Tensor.h:310
std::vector< int64_t > Shape
Shape of a N-dimensional Tensor represented as the size in each dimension. Can be -1 in case of dynam...
Definition Tensor.h:75
See also
fromData(const std::vector<T>&, const Shape&) for a copy version.
reduce.cpp for an example of using this function.

◆ map() [1/2]

template<typename Func >
tl::expected< Tensor, NeuralError > NN::Tensor::map ( Func &&  f) const
inline

Map each element of the Tensor to a new value by applying a given function element-wise. This can be used to change the datatype as well.

Template Parameters
FuncTemplated function type (T->V) where T matches the current data type and V is a valid new data type.
Parameters
fThe mapping function which is applied to each element.
Returns
tl::expected<Tensor, NeuralError> Returns a new Tensor or an error object.

This function applies the given function to each element of the Tensor and returns a new Tensor with the mapped values. The function must accept an element of the current data type and return a value of the new data type.

Example usage: convert a Tensor of uint8_t values to float values.

NN::Tensor tensor = ... // Tensor(shape=[512,512], dtype=uint8)
auto result = tensor.map([](uint8_t val) -> float {
return static_cast<float>(val) / 255.0f; // Normalize to [0,1]
});
if (!result) {
std::cerr << "ERROR: " << result.error() << std::endl;
return -1;
}
NN::Tensor normalized = std::move(result.value());
std::cout << normalized.toString() << std::endl; // Tensor(shape=[512,512], dtype=float)
A Tensor represents a N-dimensional array containing elements of the same type. Can be used as input ...
Definition Tensor.h:201
std::string toString() const
Create a human-readable string representation containing the Tensors shape and data type.
Definition Tensor.cpp:232
tl::expected< Tensor, NeuralError > map(Func &&f) const
Map each element of the Tensor to a new value by applying a given function element-wise....
Definition Tensor.h:615
See also
Tensor::map(Func&& f, int axis) for a version that adds a new dimension.

◆ map() [2/2]

template<typename Func >
tl::expected< Tensor, NeuralError > NN::Tensor::map ( Func &&  func,
int  axis 
) const
inline

Map each element of the Tensor to an array of new values by applying a given function element-wise. This adds a new dimension in the given axis.

Template Parameters
FuncTemplated function type (T->std::array<N,U>) where T matches the current data type and U is a valid new data type.
Parameters
funcThe mapping function which is applied to each element.
axisThe axis to insert the new dimension.
Returns
tl::expected<Tensor, NeuralError> Returns a new Tensor or an error object.

Example usage: Map a 2D-Tensor of class-indices to a 3D-Tensor with RGB colors assigned to each class. The mapping function therefore maps a class index (int64_t) to a RGB color (std::array<3,uint8_t>). This will create a new dimension in the output Tensor at the given axis (in this case appends the new dimension at the front).

NN::Tensor classes = ... // Tensor(shape=[512,512], dtype=int64)
std::vector<std::array<uint8_t,3>> colors = { {255,0,0}, {127,127,127}, ... }; // a color per class
auto result = classes.map([colors](int64_t index){
return colors[index];
}, 0);
if (!result) {
std::cerr << "ERROR: " << result.error() << std::endl;
return -1;
}
NN::Tensor colorized = std::move(result.value());
std::cout << colorized.toString() << std::endl; // Tensor(shape=[3,512,512], dtype=uint8)
See also
Tensor::map(Func&& f) for a version that does not add a new dimension.
map.cpp for an example of using this function.

◆ numElements()

int64_t NN::Tensor::numElements ( ) const

Returns the number of elements contained in the Tensor.

Returns
int64_t The number of elements.

◆ reduce()

template<typename Op >
tl::expected< Tensor, NeuralError > NN::Tensor::reduce ( const Op &  op,
uint64_t  axis 
) const
inline

Reduce the Tensor along a given axis by applying an accumulative operation.

Template Parameters
OpTemplated to work with different data types.
Parameters
opAn accumulative operation like ReduceMin/ReduceMax/ReduceSum.
axisThe axis in which we apply the operation, in the output this axis will have size 1.
Returns
tl::expected<Tensor, NeuralError> Returns a reduced Tensor or an error object.

This function applies the specified reduction operation along the given axis. The output tensor will have the same shape as the input tensor, except for the reduced axis, which will have size 1.

NN::Tensor tensor = ...; // some tensor with shape [N, C, H, W]
auto reduced_tensor = tensor.value().reduce(ReduceSum{}, 1);
reduced_tensor.value().toString(); // Should print something like "Tensor(shape=[N, 1, H, W], dtype=float)"
tl::expected< Tensor, NeuralError > reduce(const Op &op, uint64_t axis) const
Reduce the Tensor along a given axis by applying an accumulative operation.
Definition Tensor.h:483
Reduces a Tensor by summing its elements along a specified axis.
Definition ReduceOps.h:37
See also
ReduceOps.h for the supported operations.
reduce.cpp for an example of using this function.

◆ reduceWithIndex()

template<typename Op >
tl::expected< Tensor, NeuralError > NN::Tensor::reduceWithIndex ( const Op &  op,
uint64_t  axis 
) const
inline

Reduce the Tensor along a given axis by applying an accumulative operation. The dimension in the rduced axis will be 1 after this.

Template Parameters
OpTemplated to work with different data types.
Parameters
opAn indexed reduction operation like ReduceArgMax.
axisThe axis in which we apply the operation, in the output this axis will have size 1.
Returns
tl::expected<Tensor, NeuralError> Returns a reduced Tensor or an error object.

Example usage for applying an ArgMax-Operation to a 2D-Tensor. Assume the Tensor contains a batch of K-dimesnional feature vectors and batch size is N. Then the shape is [N,K]. We want to obtain the index of the maximum value for each vector, so the output will have shape [N,1]:

Tensor tensor = ... // shape is [N,K]
auto result = tensor.reduceWithIndex(ReduceArgMax{},1); // apply arg-max to axis 1 (corresponds to K)
if (!result){
std::cout << "ERROR: " << result.error() << std::endl;
return -1;
}
Tensor argmax_tensor = result.value();
std::cout << "Resulting tensor: " << argmax_tensor.toString() << std::endl;
// Resulting tensor: tensor(shape=[N,1], dtype=int64)
tl::expected< Tensor, NeuralError > reduceWithIndex(const Op &op, uint64_t axis) const
Reduce the Tensor along a given axis by applying an accumulative operation. The dimension in the rduc...
Definition Tensor.h:551
Reduces a Tensor by finding the index of the maximum value along a specified axis.
Definition ReduceOps.h:123
See also
ReduceOps.h for the supported operations.
reduceWithIndex.cpp for an example of using this function.

◆ reshape()

tl::expected< void, NeuralError > NN::Tensor::reshape ( const Shape newShape)

Reshape will interprete the data elements contained in the Tensor as a different shape. This does not move any elements!

Parameters
newShapeThe new shape, it must match the Tensors number of elements.
Returns
tl::expected<void, NeuralError> Returns an error object only if the new shape is invalid.

◆ shape()

const Shape & NN::Tensor::shape ( ) const
inline

Readonly access to the shape of the tensor. Valid tensors ensure the shape is static, so no dimension is -1.

Returns
const Shape& access to the shape object.

◆ squeeze() [1/2]

tl::expected< void, NeuralError > NN::Tensor::squeeze ( )

Squeeze the Tensor by removing dimensions of size 1. This operation is performed inplace.

Returns
tl::expected<void, NeuralError> This should never fail.

◆ squeeze() [2/2]

tl::expected< void, NeuralError > NN::Tensor::squeeze ( int64_t  axis)

Squeeze the Tensor by removing a specific dimension of size 1.

Parameters
axisThe axis to remove. This must be in range [0,shape.size()-1] and the dimension at this axis must be 1.
Returns
tl::expected<void, NeuralError> Returns an error object if the axis is invalid or the dimension is not 1.

◆ toCvMat()

tl::expected< cv::Mat, NeuralError > NN::Tensor::toCvMat ( ) const

Create a cv::Mat from a Tensor. In case of 2/3 dimensions this will convert back to CVs HWC layout. Returns an error for dimensions other than 2 or 3.

Returns
tl::expected<cv::Mat, NeuralError> A cv::Mat object with the data in HWC format or an error object.

◆ toString()

std::string NN::Tensor::toString ( ) const

Create a human-readable string representation containing the Tensors shape and data type.

Returns
std::string A string like "Tensor(shape=[3,512,512], dtype=float)".

◆ toVector()

template<typename T >
tl::expected< std::vector< T >, NeuralError > NN::Tensor::toVector ( ) const
inline

Create a vector containing the data from the Tensor.

Template Parameters
TThe datatype of the vector. This must match the Tensors current type!
Returns
tl::expected<std::vector<T>, NeuralError> Returns the data vector or an error object if the Tensor does not contain the requested data type.

This function extracts the data from the Tensor and returns it as a vector of the specified type. If the Tensor does not contain the requested data type, an error object is returned.

// Create a Tensor with float data
Shape shape = {2, 3}; // 2x3 tensor (CHW format)
std::vector<float> data = {1.0, 2.0, 3.0,
4.0, 5.0, 6.0};
auto tensor = Tensor::fromData(std::move(data), shape).value();
TensorType type = tensor.dtype(); // Should be TensorType::Float
// Convert Tensor to vector<float>
auto vec = tensor.toVector<float>();
if (vec) {
// Successfully converted to vector<float>
std::cout << "Tensor data: ";
for (const auto& val : vec.value()) {
std::cout << val << " ";
}
std::cout << std::endl;
}
const Shape & shape() const
Readonly access to the shape of the tensor. Valid tensors ensure the shape is static,...
Definition Tensor.h:405
TensorType
TensorType encapsulates the supported data types of tensor elements. The supported types are:
Definition Tensor.h:115

◆ unsqueeze()

tl::expected< void, NeuralError > NN::Tensor::unsqueeze ( int64_t  axis)

Add a new dimension of size 1 at the specified axis.

Parameters
axisThe axis to insert the new dimension. This must be in range [0,shape.size()].
Returns
tl::expected<void, NeuralError> Returns an error object if the axis is invalid.

The documentation for this class was generated from the following files: