Image operations

Note

A practical example of the vast majority of the operations in this page are included in a working example in our GitHub respository

Transformations

Shift

Tensor *Tensor::shift(vector<int> shift, WrappingMode mode = WrappingMode::Constant, float cval = 0.0f)

Shift the tensor. The array is shifted using spline interpolation. Points outside the boundaries of the input are filled according to the given mode.

Parameters
  • shift – vector of shifts along the axes.

  • mode – Must be one of the following:

    • WrappingMode::Constant: Input extended by the value in cval (v v v v | a b c d | v v v v)

    • WrappingMode::Reflect: Input extended by reflecting about the edge of the last pixel (d c b a | a b c d | d c b a)

    • WrappingMode::Nearest: Input extended by replicating the last pixel (a a a a | a b c d | d d d d)

    • WrappingMode::Mirror: Input extended by reflecting about the center of the las pixel (d c b | a b c d | c b a)

    • WrappingMode::Wrap: Input extended by wrapping around the oposite edge (a b c d | a b c d | a b c d)

    • WrappingMode::Original: Input extended by placing the original image in the background.

  • cval – Value to fill past edges of input if mode is WrappingMode::Constant

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Shifts t1 50 pixels in y and 100 in x - WP: Constant
Tensor* t2 = t1->shift({50, 100}, WrappingMode::Constant, 0.0f);
t2->save("lena_shift.jpg");

// Other ways
Tensor::shift(t1, t2, {50, 100}, WrappingMode::Constant, 0.0f);  // static
Shift operation on Lena
Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Shifts t1 50 pixels in y and 100 in x - WP: Original
Tensor* t2 = t1->shift({50, 100}, WrappingMode::Original, 0.0f);
t2->save("lena_shift.jpg");

// Other ways
Tensor::shift(t1, t2, {50, 100}, WrappingMode::Original, 0.0f);  // static
Shift operation on Lena (WP: Original)

Rotate

Tensor *Tensor::rotate(float angle, vector<int> offset_center = {0, 0}, WrappingMode mode = WrappingMode::Constant, float cval = 0.0f)

Rotate the tensor. The array is rotated in the plane dfined by the two axes given by the axes parameter using spline interpolation.

Parameters
  • angle – The rotation angle in degrees.

  • offset_center – The center where to perform the rotation

  • mode – Must be one of the following:

    • WrappingMode::Constant: Input extended by the value in cval (v v v v | a b c d | v v v v)

    • WrappingMode::Reflect: Input extended by reflecting about the edge of the last pixel (d c b a | a b c d | d c b a)

    • WrappingMode::Nearest: Input extended by replicating the last pixel (a a a a | a b c d | d d d d)

    • WrappingMode::Mirror: Input extended by reflecting about the center of the las pixel (d c b | a b c d | c b a)

    • WrappingMode::Wrap: Input extended by wrapping around the oposite edge (a b c d | a b c d | a b c d)

    • WrappingMode::Original: Input extended by placing the original image in the background.

  • cval – Value to fill past edges of input if mode is WrappingMode::Constant

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Rotates t1 30 degrees - WP: Constant
Tensor* t2 = t1->rotate(30.0f, {0,0}, WrappingMode::Constant);
t2->save("lena_rotate_wm_const.jpg");

// Other ways
Tensor::rotate(t1, t2, 30.0f, {0,0}, WrappingMode::Constant);  // Static
Rotate operation on Lena (WP: Constant)

Scale

Tensor *Tensor::scale(vector<int> new_shape, WrappingMode wrapping_mode = WrappingMode::Constant, float cval = 0.0f, TransformationMode coordinate_transformation_mode = TransformationMode::Asymmetric, bool keep_size = false)

Scale the tensor. The array is scaled using spline interpolation.

Parameters
  • new_shape – Vector with the target size.

  • wrapping_mode – Must be one of the following:

    • WrappingMode::Constant: Input extended by the value in cval (v v v v | a b c d | v v v v)

    • WrappingMode::Reflect: Input extended by reflecting about the edge of the last pixel (d c b a | a b c d | d c b a)

    • WrappingMode::Nearest: Input extended by replicating the last pixel (a a a a | a b c d | d d d d)

    • WrappingMode::Mirror: Input extended by reflecting about the center of the las pixel (d c b | a b c d | c b a)

    • WrappingMode::Wrap: Input extended by wrapping around the oposite edge (a b c d | a b c d | a b c d)

    • WrappingMode::Original: Input extended by placing the original image in the background.

  • cval – Value to fill past edges of input if mode is WrappingMode::Constant

  • coordinate_transformation_mode – This attribute describes how to transform the coordinate in the resized tensor to the coordinate in the original tensor.

    • TransformationMode::HalfPixel: x_original = (x_resized + 0.5) / scale - 0.5

    • TransformationMode::PytorchHalfPixel: x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : 0

    • TransformationMode::AlignCorners: x_original = x_resized * (length_original - 1) / (length_resized - 1)

    • TransformationMode::Asymmetric: x_original = x_resized / scale

    • TransformationMode::TFCropAndResize: x_original = length_resized > 1 ? start_x * (length_original - 1) + x_resized * (end_x - start_x) * (length_original - 1) / (length_resized - 1) : 0.5 * (start_x + end_x) * (length_original - 1)

  • keep_size – Keep original size

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Scale to 100x100 pixels
Tensor* t2 = t1->scale({100, 100}); // keep_size==false
t2->save("lena_scale_100x100.jpg");

// Other ways
Tensor::scale(t1, t2, {100, 100});  // Static
Scale operation on Lena (to 100x100)
Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Scale to 880x880 pixels (virtual) but keeping its original size
Tensor* t2 = t1->scale({880, 880}, WrappingMode::Constant, 0.0f, true); // keep_size==true
t2->save("lena_scale_x2_fixed.jpg");

// Other ways
Tensor::scale(t1, t2, {880, 880});  // Static
Scale operation on Lena (x2, fixed)

Flip

Tensor *Tensor::flip(int axis = 0)

Flip the tensor.

Parameters

axis – The axis used to flip the tensor.

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Flip along horizontal axis
Tensor* t2 = t1->flip(1);
t2->save("lena_flip_h.jpg");

// Other ways
Tensor::flip(t1, t2, 1);  // Static
Flip operation on Lena

Crop

Tensor *Tensor::crop(vector<int> coords_from, vector<int> coords_to, float cval = 0.0f, bool keep_size = false)

Crop the tensor.

Parameters
  • coords_from – Coordinates of the initial point of the crop.

  • coords_to – Coordinates of the final point of the crop.

  • cval – Value to fill past edges.

  • keep_size – Keep original size

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Crop a rectangle
Tensor* t2 = t1->crop({50, 250}, {250, 400});  // keep_size==false
t2->save("lena_cropped_small.jpg");

// Other ways
Tensor::crop(t1, t2, {50, 250}, {250, 400});  // Static
Crop operation on Lena (Small)
Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Crop a rectangle
Tensor* t2 = t1->crop({50, 250}, {250, 400}, 0.0f, true);  // keep_size==true
t2->save("lena_cropped_big.jpg");

// Other ways
Tensor::crop(t1, t2, {50, 250}, {250, 400});  // Static
Crop operation on Lena (Big)

Crop & Scale

Tensor *Tensor::crop_scale(vector<int> coords_from, vector<int> coords_to, WrappingMode mode = WrappingMode::Constant, float cval = 0.0f)

Crop and scale the tensor. The array is scaled using spline interpolation.

Parameters
  • coords_from – Coordinates of the initial point of the crop.

  • coords_to – Coordinates of the final point of the crop.

  • mode – Must be one of the following:

    • WrappingMode::Constant: Input extended by the value in cval (v v v v | a b c d | v v v v)

    • WrappingMode::Reflect: Input extended by reflecting about the edge of the last pixel (d c b a | a b c d | d c b a)

    • WrappingMode::Nearest: Input extended by replicating the last pixel (a a a a | a b c d | d d d d)

    • WrappingMode::Mirror: Input extended by reflecting about the center of the las pixel (d c b | a b c d | c b a)

    • WrappingMode::Wrap: Input extended by wrapping around the oposite edge (a b c d | a b c d | a b c d)

    • WrappingMode::Original: Input extended by placing the original image in the background.

  • cval – Value to fill past edges of input if mode is WrappingMode::Constant

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Crop and scale
Tensor* t2 = t1->crop_scale({50, 250}, {250, 400});
t2->save("lena_crop_scale.jpg");

// Other ways
Tensor::crop_scale(t1, t2, {50, 250}, {250, 400});  // Static
Crop and Scale operation on Lena

Cutout

Tensor *Tensor::cutout(vector<int> coords_from, vector<int> coords_to, float cval = 0.0f)

Set to a constant value a region of the tensor.

Parameters
  • coords_from – Coordinates of the initial point of the crop.

  • coords_to – Coordinates of the final point of the crop.

  • cval – Value to fill the crop region with.

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_();  // 4D tensor needed

// Cutout
Tensor* t2 = t1->cutout({50, 250}, {250, 400});
t2->save("lena_cutout.jpg");

// Other ways
Tensor::cutout(t1, t2, {50, 250}, {250, 400});  // Static
Cutout operation on Lena

Pad

Tensor *Tensor::pad(vector<int> pads, float cval = 0.0f)

Pads a tensor.

Parameters
  • pads – Padding on each border (top-bottom, left-right) or (top, right, bottom, left)

  • cval – Value to fill the padded region

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_();  // 4D tensor needed

// Pad
Tensor* t2 = t1->pad({50, 50});
t2->save("lena_pad.jpg");

// Other ways
Tensor::pad(t1, t2, {50, 50});  // Static
Pad operation on Lena

Data augmentations

Shift Random

Tensor *Tensor::shift_random(vector<float> factor_x, vector<float> factor_y, WrappingMode mode = WrappingMode::Constant, float cval = 0.0f)

Shift the tensor with a random shift value taken from a specified range. The array is shifted using spline interpolation. Points outside the boundaries of the input are filled according to the given mode.

Parameters
  • factor_x – vector with the lower and upper values for shift in axis x.

  • factor_y – vector with the lower and upper values for shift in axis y.

  • mode – Must be one of the following:

    • WrappingMode::Constant: Input extended by the value in cval (v v v v | a b c d | v v v v)

    • WrappingMode::Reflect: Input extended by reflecting about the edge of the last pixel (d c b a | a b c d | d c b a)

    • WrappingMode::Nearest: Input extended by replicating the last pixel (a a a a | a b c d | d d d d)

    • WrappingMode::Mirror: Input extended by reflecting about the center of the las pixel (d c b | a b c d | c b a)

    • WrappingMode::Wrap: Input extended by wrapping around the oposite edge (a b c d | a b c d | a b c d)

    • WrappingMode::Original: Input extended by placing the original image in the background.

  • cval – Value to fill past edges of input if mode is WrappingMode::Constant

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Shift randomly image +-35% (range for the Y and X axis)
Tensor* t2 = t1->shift_random({-0.35f, +0.35f}, {-0.35f, +0.35f}, WrappingMode::Constant, 0.0f);
t2->save("lena_rnd_shift.jpg");

// Other ways
Tensor::shift_random(t1, t2, {-0.35f, +0.35f}, {-0.35f, +0.35f}, WrappingMode::Constant, 0.0f);  // static
Random shift operation on Lena

Rotate Random

Tensor *Tensor::rotate_random(vector<float> factor, vector<int> offset_center = {0, 0}, WrappingMode mode = WrappingMode::Constant, float cval = 0.0f)

Rotate the tensor with a random angle in a specified range. The array is rotated in the plane dfined by the two axes given by the axes parameter using spline interpolation.

Parameters
  • factor – The rotation angle range in degrees.

  • offset_center – The center where to perform the rotation

  • mode – Must be one of the following:

    • WrappingMode::Constant: Input extended by the value in cval (v v v v | a b c d | v v v v)

    • WrappingMode::Reflect: Input extended by reflecting about the edge of the last pixel (d c b a | a b c d | d c b a)

    • WrappingMode::Nearest: Input extended by replicating the last pixel (a a a a | a b c d | d d d d)

    • WrappingMode::Mirror: Input extended by reflecting about the center of the las pixel (d c b | a b c d | c b a)

    • WrappingMode::Wrap: Input extended by wrapping around the oposite edge (a b c d | a b c d | a b c d)

    • WrappingMode::Original: Input extended by placing the original image in the background.

  • cval – Value to fill past edges of input if mode is WrappingMode::Constant

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Rotate image randomly +-60 degrees, using the coordinates (220, 220) as anchor (from the center)
Tensor* t2 = t1->rotate_random({-60.0f, +60.0f}, {220, 220});
t2->save("lena_rnd_rotate.jpg");

// Other ways
Tensor::rotate_random(t1, t2, {-60.0f, +60.0f}, {220, 220});
Random rotate operation on Lena

Scale Random

Tensor *Tensor::scale_random(vector<float> factor, WrappingMode mode = WrappingMode::Constant, float cval = 0.0f, TransformationMode coordinate_transformation_mode = TransformationMode::Asymmetric)

Scale the tensor wit a random factor in a specified range. The array is scaled using spline interpolation.

Parameters
  • factor – Vector with minimum and maximum scale factors.

  • mode – Must be one of the following:

    • WrappingMode::Constant: Input extended by the value in cval (v v v v | a b c d | v v v v)

    • WrappingMode::Reflect: Input extended by reflecting about the edge of the last pixel (d c b a | a b c d | d c b a)

    • WrappingMode::Nearest: Input extended by replicating the last pixel (a a a a | a b c d | d d d d)

    • WrappingMode::Mirror: Input extended by reflecting about the center of the las pixel (d c b | a b c d | c b a)

    • WrappingMode::Wrap: Input extended by wrapping around the oposite edge (a b c d | a b c d | a b c d)

    • WrappingMode::Original: Input extended by placing the original image in the background.

  • cval – Value to fill past edges of input if mode is WrappingMode::Constant

  • coordinate_transformation_mode – This attribute describes how to transform the coordinate in the resized tensor to the coordinate in the original tensor.

    • TransformationMode::HalfPixel: x_original = (x_resized + 0.5) / scale - 0.5

    • TransformationMode::PytorchHalfPixel: x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : 0

    • TransformationMode::AlignCorners: x_original = x_resized * (length_original - 1) / (length_resized - 1)

    • TransformationMode::Asymmetric: x_original = x_resized / scale

    • TransformationMode::TFCropAndResize: x_original = length_resized > 1 ? start_x * (length_original - 1) + x_resized * (end_x - start_x) * (length_original - 1) / (length_resized - 1) : 0.5 * (start_x + end_x) * (length_original - 1)

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Scale image randomly +-25%
Tensor* t2 = t1->scale_random({0.75f, 1.25f});
t2->save("lena_rnd_scale_nn.jpg");

// Other ways
Tensor::scale_random(t1, t2, {0.75f, 1.25f});
Random scale operation on Lena

Flip Random

Tensor *Tensor::flip_random(int axis)

Flip the tensor with some probability.

Parameters

axis – The axis used to flip the tensor.

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Flip randomly on the horizontal axis (50% change)
Tensor* t2 = t1->flip_random(1);
t2->save("lena_rnd_flip.jpg");

// Other ways
Tensor::flip_random(t1, t2, 1);
Random flip operation on Lena

Crop Random

Tensor *Tensor::crop_random(int height, int width, float cval = 0.0f, bool keep_size = false)

Crop randomly the tensor.

Parameters
  • height – Height of the crop (must be smaller than the original image)

  • width – Width of the crop (must be smaller than the original image)

  • cval

  • keep_size – Keep original size

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Crop t1 randomly with a crop size with height=200px and width=150px
Tensor* t2 = t1->crop_random(200, 150);
t2->save("lena_rnd_crop.jpg");

// Other ways
Tensor::crop_random(t1, t2);
Random crop operation on Lena

Crop & Scale Random

Tensor *Tensor::crop_scale_random(vector<float> factor, WrappingMode mode = WrappingMode::Constant, float cval = 0.0f)

Crop randomly and scale the tensor with a random factor in a specified range. The array is scaled using spline interpolation.

Parameters
  • factor – Vector with minimum and maximum scale factors.

  • mode – Must be one of the following:

    • WrappingMode::Constant: Input extended by the value in cval (v v v v | a b c d | v v v v)

    • WrappingMode::Reflect: Input extended by reflecting about the edge of the last pixel (d c b a | a b c d | d c b a)

    • WrappingMode::Nearest: Input extended by replicating the last pixel (a a a a | a b c d | d d d d)

    • WrappingMode::Mirror: Input extended by reflecting about the center of the las pixel (d c b | a b c d | c b a)

    • WrappingMode::Wrap: Input extended by wrapping around the oposite edge (a b c d | a b c d | a b c d)

    • WrappingMode::Original: Input extended by placing the original image in the background.

  • cval – Value to fill past edges of input if mode is WrappingMode::Constant

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Crop a path with size 65-95% of t1, and scale it to the t2 size
Tensor* t2 = t1->crop_scale_random({0.65f, 0.95f});
t2->save("lena_rnd_crop_scale_nn.jpg");

// Other ways
Tensor::crop_scale_random(t1, t2, {0.65f, 0.95f});
Random Crop & Scale operation on Lena

Cutout Random

Tensor *Tensor::cutout_random(vector<float> factor_x, vector<float> factor_y, float cval = 0.0f)

Set to a constant value a region of the tensor.

Parameters
  • factor_x – vector with the lower and upper values for cut in axis x.

  • factor_y – vector with the lower and upper values for cut in axis y.

  • cval – Value to fill the crop region with.

Tensor* t1 = Tensor::load("lena.jpg"); t1->unsqueeze_(); //4D tensor needed

// Cutout a patch with size 10-30% of t1 (height and width)
Tensor* t2 = t1->cutout_random({0.10f, 0.30f}, {0.10f, 0.30f});
t2->save("lena_rnd_cutout.jpg");

// Other ways
Tensor::cutout_random(t1, t2, {0.10f, 0.30f}, {0.10f, 0.30f});
Random cutout operation on Lena