44 inline uint8_t nearest_interpolation(
const uint8_t *in_ptr,
int x,
int y,
size_t stride)
46 return in_ptr[x + y * stride];
51 : _func(nullptr), _input(nullptr), _output(nullptr), _constant_border_value(0), _matrix()
67 (this->*_func)(window);
76 _constant_border_value = constant_border_value;
81 _func = &INEWarpKernel::warp_undefined;
84 _func = &INEWarpKernel::warp_constant;
87 _func = &INEWarpKernel::warp_replicate;
105 input_valid_region.anchor[0] + input_valid_region.shape[0] +
border_size().
right,
106 input_valid_region.anchor[1] + input_valid_region.shape[1] +
border_size().
bottom);
113 INEKernel::configure(win);
116 template <InterpolationPolicy
interpolation>
136 const float M00 = _matrix[0];
137 const float M10 = _matrix[1];
138 const float M01 = _matrix[0 + 1 * 2];
139 const float M11 = _matrix[1 + 1 * 2];
140 const float M02 = _matrix[0 + 2 * 2];
141 const float M12 = _matrix[1 + 2 * 2];
144 const float start_x0 = M00 * window.
x().
start();
145 const float start_y0 = M10 * window.
x().
start();
148 int y_cur = window.
y().
start();
149 int z_cur = window.
z().
start();
150 int d3_cur = window[3].start();
151 int d4_cur = window[4].start();
152 int d5_cur = window[5].start();
155 float const_x0 = M01 * y_cur + M02;
156 float const_y0 = M11 * y_cur + M12;
159 float x0 = start_x0 + const_x0;
160 float y0 = start_y0 + const_y0;
165 if((y_cur !=
id.y()) || (z_cur !=
id.z()) || (d3_cur !=
id[3]) || (d4_cur !=
id[4]) || (d5_cur !=
id[5]))
173 const_x0 = M01 * y_cur + M02;
174 const_y0 = M11 * y_cur + M12;
176 x0 = start_x0 + const_x0;
177 y0 = start_y0 + const_y0;
182 if((min_y <= y0) && (y0 < max_y) && (min_x <= x0) && (x0 < max_x))
184 switch(interpolation)
187 *out.
ptr() = nearest_interpolation(in.
ptr(), x0, y0, stride);
203 template <InterpolationPolicy
interpolation>
223 const float M00 = _matrix[0];
224 const float M10 = _matrix[1];
225 const float M01 = _matrix[0 + 1 * 2];
226 const float M11 = _matrix[1 + 1 * 2];
227 const float M02 = _matrix[0 + 2 * 2];
228 const float M12 = _matrix[1 + 2 * 2];
231 const float start_x0 = M00 * window.
x().
start();
232 const float start_y0 = M10 * window.
x().
start();
235 int y_cur = window.
y().
start();
236 int z_cur = window.
z().
start();
237 int d3_cur = window[3].start();
238 int d4_cur = window[4].start();
239 int d5_cur = window[5].start();
242 float const_x0 = M01 * y_cur + M02;
243 float const_y0 = M11 * y_cur + M12;
246 float x0 = start_x0 + const_x0;
247 float y0 = start_y0 + const_y0;
252 if((y_cur !=
id.y()) || (z_cur !=
id.z()) || (d3_cur !=
id[3]) || (d4_cur !=
id[4]) || (d5_cur !=
id[5]))
260 const_x0 = M01 * y_cur + M02;
261 const_y0 = M11 * y_cur + M12;
263 x0 = start_x0 + const_x0;
264 y0 = start_y0 + const_y0;
269 if((min_y <= y0) && (y0 < max_y) && (min_x <= x0) && (x0 < max_x))
271 switch(interpolation)
274 *out.
ptr() = nearest_interpolation(in.
ptr(), x0, y0, stride);
285 switch(interpolation)
288 *out.
ptr() = _constant_border_value;
292 const auto xi = utility::clamp<int>(std::floor(x0), min_x - 1, max_x);
293 const auto yi = utility::clamp<int>(std::floor(y0), min_y - 1, max_y);
294 const auto xi_1 = utility::clamp<int>(std::floor(x0 + 1), min_x - 1, max_x);
295 const auto yi_1 = utility::clamp<int>(std::floor(y0 + 1), min_y - 1, max_y);
297 const float dx = x0 - std::floor(x0);
298 const float dy = y0 - std::floor(y0);
299 const float dx1 = 1.0f - dx;
300 const float dy1 = 1.0f - dy;
302 const float a00 = *(in.
ptr() + xi + yi * stride);
303 const float a01 = *(in.
ptr() + xi_1 + yi * stride);
304 const float a10 = *(in.
ptr() + xi + yi_1 * stride);
305 const float a11 = *(in.
ptr() + xi_1 + yi_1 * stride);
307 *out.
ptr() = a00 * (dx1 * dy1) + a01 * (dx * dy1) + a10 * (dx1 * dy) + a11 * (dx * dy);
321 template <InterpolationPolicy
interpolation>
340 int y_cur = window.
y().
start();
341 int z_cur = window.
z().
start();
342 int d3_cur = window[3].start();
343 int d4_cur = window[4].start();
344 int d5_cur = window[5].start();
346 const float M00 = _matrix[0];
347 const float M10 = _matrix[1];
348 const float M01 = _matrix[0 + 1 * 2];
349 const float M11 = _matrix[1 + 1 * 2];
350 const float M02 = _matrix[0 + 2 * 2];
351 const float M12 = _matrix[1 + 2 * 2];
354 const float start_x0 = M00 * window.
x().
start();
355 const float start_y0 = M10 * window.
x().
start();
358 float const_x0 = M01 * y_cur + M02;
359 float const_y0 = M11 * y_cur + M12;
361 float x0 = start_x0 + const_x0;
362 float y0 = start_y0 + const_y0;
367 if((y_cur !=
id.y()) || (z_cur !=
id.z()) || (d3_cur !=
id[3]) || (d4_cur !=
id[4]) || (d5_cur !=
id[5]))
375 const_x0 = M01 * y_cur + M02;
376 const_y0 = M11 * y_cur + M12;
378 x0 = start_x0 + const_x0;
379 y0 = start_y0 + const_y0;
384 if((min_y <= y0) && (y0 < max_y) && (min_x <= x0) && (x0 < max_x))
386 switch(interpolation)
389 *out.
ptr() = nearest_interpolation(in.
ptr(), x0, y0, stride);
401 const auto xi = utility::clamp<int>(std::floor(x0), min_x, max_x - 1);
402 const auto yi = utility::clamp<int>(std::floor(y0), min_y, max_y - 1);
403 switch(interpolation)
406 *out.
ptr() = *(in.
ptr() + xi + yi * stride);
410 const auto xi_1 = utility::clamp<int>(std::floor(x0 + 1), min_x, max_x - 1);
411 const auto yi_1 = utility::clamp<int>(std::floor(y0 + 1), min_y, max_y - 1);
413 const float dx = x0 - std::floor(x0);
414 const float dy = y0 - std::floor(y0);
415 const float dx1 = 1.0f - dx;
416 const float dy1 = 1.0f - dy;
418 const float a00 = *(in.
ptr() + xi + yi * stride);
419 const float a01 = *(in.
ptr() + xi_1 + yi * stride);
420 const float a10 = *(in.
ptr() + xi + yi_1 * stride);
421 const float a11 = *(in.
ptr() + xi_1 + yi_1 * stride);
423 *out.
ptr() = a00 * (dx1 * dy1) + a01 * (dx * dy1) + a10 * (dx1 * dy) + a11 * (dx * dy);
437 template <InterpolationPolicy
interpolation>
460 const float M00 = _matrix[0];
461 const float M10 = _matrix[1];
462 const float M20 = _matrix[2];
463 const float M01 = _matrix[0 + 1 * 3];
464 const float M11 = _matrix[1 + 1 * 3];
465 const float M21 = _matrix[2 + 1 * 3];
466 const float M02 = _matrix[0 + 2 * 3];
467 const float M12 = _matrix[1 + 2 * 3];
468 const float M22 = _matrix[2 + 2 * 3];
471 const float start_x0 = M00 * window.
x().
start();
472 const float start_y0 = M10 * window.
x().
start();
473 const float start_z0 = M20 * window.
x().
start();
476 int y_cur = window.
y().
start();
477 int z_cur = window.
z().
start();
478 int d3_cur = window[3].start();
479 int d4_cur = window[4].start();
480 int d5_cur = window[5].start();
483 float const_x0 = M01 * y_cur + M02;
484 float const_y0 = M11 * y_cur + M12;
485 float const_z0 = M21 * y_cur + M22;
488 float x0 = start_x0 + const_x0;
489 float y0 = start_y0 + const_y0;
490 float z0 = start_z0 + const_z0;
495 if((y_cur !=
id.y()) || (z_cur !=
id.z()) || (d3_cur !=
id[3]) || (d4_cur !=
id[4]) || (d5_cur !=
id[5]))
503 const_x0 = M01 * y_cur + M02;
504 const_y0 = M11 * y_cur + M12;
505 const_z0 = M21 * y_cur + M22;
507 x0 = start_x0 + const_x0;
508 y0 = start_y0 + const_y0;
509 z0 = start_z0 + const_z0;
512 const float xn = x0 / z0;
513 const float yn = y0 / z0;
517 if((min_y <= yn) && (yn < max_y) && (min_x <= xn) && (xn < max_x))
519 switch(interpolation)
522 *out.
ptr() = nearest_interpolation(in.
ptr(), xn, yn, stride);
539 template <InterpolationPolicy
interpolation>
562 const float M00 = _matrix[0];
563 const float M10 = _matrix[1];
564 const float M20 = _matrix[2];
565 const float M01 = _matrix[0 + 1 * 3];
566 const float M11 = _matrix[1 + 1 * 3];
567 const float M21 = _matrix[2 + 1 * 3];
568 const float M02 = _matrix[0 + 2 * 3];
569 const float M12 = _matrix[1 + 2 * 3];
570 const float M22 = _matrix[2 + 2 * 3];
573 const float start_x0 = M00 * window.
x().
start();
574 const float start_y0 = M10 * window.
x().
start();
575 const float start_z0 = M20 * window.
x().
start();
578 int y_cur = window.
y().
start();
579 int z_cur = window.
z().
start();
580 int d3_cur = window[3].start();
581 int d4_cur = window[4].start();
582 int d5_cur = window[5].start();
585 float const_x0 = M01 * y_cur + M02;
586 float const_y0 = M11 * y_cur + M12;
587 float const_z0 = M21 * y_cur + M22;
590 float x0 = start_x0 + const_x0;
591 float y0 = start_y0 + const_y0;
592 float z0 = start_z0 + const_z0;
597 if((y_cur !=
id.y()) || (z_cur !=
id.z()) || (d3_cur !=
id[3]) || (d4_cur !=
id[4]) || (d5_cur !=
id[5]))
605 const_x0 = M01 * y_cur + M02;
606 const_y0 = M11 * y_cur + M12;
607 const_z0 = M21 * y_cur + M22;
609 x0 = start_x0 + const_x0;
610 y0 = start_y0 + const_y0;
611 z0 = start_z0 + const_z0;
614 const float xn = x0 / z0;
615 const float yn = y0 / z0;
618 if((min_y <= yn) && (yn < max_y) && (min_x <= xn) && (xn < max_x))
620 switch(interpolation)
623 *out.
ptr() = nearest_interpolation(in.
ptr(), xn, yn, stride);
634 switch(interpolation)
637 *out.
ptr() = _constant_border_value;
641 const auto xi = utility::clamp<int>(std::floor(xn), min_x - 1, max_x);
642 const auto yi = utility::clamp<int>(std::floor(yn), min_y - 1, max_y);
643 const auto xi_1 = utility::clamp<int>(std::floor(xn + 1), min_x - 1, max_x);
644 const auto yi_1 = utility::clamp<int>(std::floor(yn + 1), min_y - 1, max_y);
646 const float dx = xn - std::floor(xn);
647 const float dy = yn - std::floor(yn);
648 const float dx1 = 1.0f - dx;
649 const float dy1 = 1.0f - dy;
651 const float a00 = *(in.
ptr() + xi + yi * stride);
652 const float a01 = *(in.
ptr() + xi_1 + yi * stride);
653 const float a10 = *(in.
ptr() + xi + yi_1 * stride);
654 const float a11 = *(in.
ptr() + xi_1 + yi_1 * stride);
656 *out.
ptr() = a00 * (dx1 * dy1) + a01 * (dx * dy1) + a10 * (dx1 * dy) + a11 * (dx * dy);
671 template <InterpolationPolicy
interpolation>
690 int y_cur = window.
y().
start();
691 int z_cur = window.
z().
start();
692 int d3_cur = window[3].start();
693 int d4_cur = window[4].start();
694 int d5_cur = window[5].start();
701 const float M00 = _matrix[0];
702 const float M10 = _matrix[1];
703 const float M20 = _matrix[2];
704 const float M01 = _matrix[0 + 1 * 3];
705 const float M11 = _matrix[1 + 1 * 3];
706 const float M21 = _matrix[2 + 1 * 3];
707 const float M02 = _matrix[0 + 2 * 3];
708 const float M12 = _matrix[1 + 2 * 3];
709 const float M22 = _matrix[2 + 2 * 3];
712 const float start_x0 = M00 * window.
x().
start();
713 const float start_y0 = M10 * window.
x().
start();
714 const float start_z0 = M20 * window.
x().
start();
717 float const_x0 = M01 * y_cur + M02;
718 float const_y0 = M11 * y_cur + M12;
719 float const_z0 = M21 * y_cur + M22;
722 float x0 = start_x0 + const_x0;
723 float y0 = start_y0 + const_y0;
724 float z0 = start_z0 + const_z0;
729 if((y_cur !=
id.y()) || (z_cur !=
id.z()) || (d3_cur !=
id[3]) || (d4_cur !=
id[4]) || (d5_cur !=
id[5]))
737 const_x0 = M01 * y_cur + M02;
738 const_y0 = M11 * y_cur + M12;
739 const_z0 = M21 * y_cur + M22;
741 x0 = start_x0 + const_x0;
742 y0 = start_y0 + const_y0;
743 z0 = start_z0 + const_z0;
746 const float xn = x0 / z0;
747 const float yn = y0 / z0;
750 if((min_y <= yn) && (yn < max_y) && (min_x <= xn) && (xn < max_x))
752 switch(interpolation)
755 *out.
ptr() = nearest_interpolation(in.
ptr(), xn, yn, stride);
767 const auto xi = utility::clamp<int>(std::floor(xn), min_x, max_x - 1);
768 const auto yi = utility::clamp<int>(std::floor(yn), min_y, max_y - 1);
769 switch(interpolation)
772 *out.
ptr() = *(in.
ptr() + xi + yi * stride);
776 const auto xi_1 = utility::clamp<int>(std::floor(xn + 1), min_x, max_x - 1);
777 const auto yi_1 = utility::clamp<int>(std::floor(yn + 1), min_y, max_y - 1);
779 const float dx = xn - std::floor(xn);
780 const float dy = yn - std::floor(yn);
781 const float dx1 = 1.0f - dx;
782 const float dy1 = 1.0f - dy;
784 const float a00 = *(in.
ptr() + xi + yi * stride);
785 const float a01 = *(in.
ptr() + xi_1 + yi * stride);
786 const float a10 = *(in.
ptr() + xi + yi_1 * stride);
787 const float a11 = *(in.
ptr() + xi_1 + yi_1 * stride);
789 *out.
ptr() = a00 * (dx1 * dy1) + a01 * (dx * dy1) + a10 * (dx1 * dy) + a11 * (dx * dy);
BorderMode
Methods available to handle borders.
unsigned int top
top of the border
Window calculate_max_window(const ValidRegion &valid_region, const Steps &steps, bool skip_border, BorderSize border_size)
const Window & window() const
The maximum window the kernel can be executed on.
TensorShape shape
Shape of the valid region.
Container for 2D border size.
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
void run(const Window &window, const ThreadInfo &info) override
Execute the kernel on the passed window.
1 channel, 1 U8 per channel
INEWarpKernel()
Default constructor.
Output values are defined by bilinear interpolation between the pixels.
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Describe one of the image's dimensions with a start, end and step.
unsigned int bottom
bottom of the border
constexpr const Dimension & z() const
Alias to access the third dimension of the window.
Output values are defined to match the source pixel whose center is nearest to the sample position...
Interface for Neon tensor.
Copyright (c) 2017-2021 Arm Limited.
virtual ValidRegion valid_region() const =0
Valid region of the tensor.
Implementation of a static rectangular access pattern.
static constexpr size_t DimX
Alias for dimension 0 also known as X dimension.
bool update_window_and_padding(Window &win, Ts &&... patterns)
Update window and padding size for each of the access patterns.
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
Class to describe a number of elements in each dimension.
Implementation of a row access pattern.
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor's metadata.
constexpr uint8_t * ptr() const
Return a pointer to the current pixel.
void set(size_t dimension, const Dimension &dim)
Set the values of a given dimension.
Template interface for the kernel to compute warp affine.
BorderSize border_size() const override
The size of the border for that kernel.
unsigned int left
left of the border
unsigned int right
right of the border
#define ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(k)
#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
static constexpr size_t DimY
Alias for dimension 1 also known as Y dimension.
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
Information about executing thread and CPU.
Borders are left undefined.
Pixels outside the image are assumed to have the same value as the closest image pixel.
constexpr const Dimension & y() const
Alias to access the second dimension of the window.
void execute_window_loop(const Window &w, L &&lambda_function, Ts &&... iterators)
Iterate through the passed window, automatically adjusting the iterators and calling the lambda_funct...
virtual const Strides & strides_in_bytes() const =0
The strides in bytes for accessing each dimension of the tensor.
Container for valid region of a window.
T pixel_bilinear_c1(const T *first_pixel_ptr, size_t stride, float x, float y)
Return the pixel at (x,y) using bilinear interpolation.
Iterator updated by execute_window_loop for each window element.
constexpr int start() const
Return the start of the dimension.
Describe a multidimensional execution window.
Coordinates anchor
Anchor for the start of the valid region.
Template interface for the kernel to compute warp perspective.
#define ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(f, s)
virtual void configure(const ITensor *input, ITensor *output, const std::array< float, 9 > &matrix, BorderMode border_mode, uint8_t constant_border_value)
Initialise the kernel's input, output and border mode.
constexpr const Dimension & x() const
Alias to access the first dimension of the window.