diff options
Diffstat (limited to 'arm_compute/core/Helpers.h')
-rw-r--r-- | arm_compute/core/Helpers.h | 66 |
1 files changed, 57 insertions, 9 deletions
diff --git a/arm_compute/core/Helpers.h b/arm_compute/core/Helpers.h index b6461bc47a..6e4d987180 100644 --- a/arm_compute/core/Helpers.h +++ b/arm_compute/core/Helpers.h @@ -26,12 +26,14 @@ #include "arm_compute/core/CL/CLTypes.h" #include "arm_compute/core/Coordinates.h" +#include "arm_compute/core/Error.h" #include "arm_compute/core/IAccessWindow.h" #include "arm_compute/core/Steps.h" #include "arm_compute/core/Strides.h" #include "arm_compute/core/TensorShape.h" #include "arm_compute/core/Types.h" #include "arm_compute/core/Window.h" + #include <array> #include <cstddef> #include <cstdint> @@ -82,9 +84,9 @@ struct is_contained<T, std::tuple<U, Ts...>> : is_contained<T, std::tuple<Ts...> } /** Computes bilinear interpolation using the pointer to the top-left pixel and the pixel's distance between - * the real coordinates and the smallest following integer coordinates. + * the real coordinates and the smallest following integer coordinates. Input must be in single channel format. * - * @param[in] pixel_ptr Pointer to the top-left pixel value. Format: Single channel U8 + * @param[in] pixel_ptr Pointer to the top-left pixel value of a single channel input. * @param[in] stride Stride to access the bottom-left and bottom-right pixel values * @param[in] dx Pixel's distance between the X real coordinate and the smallest X following integer * @param[in] dy Pixel's distance between the Y real coordinate and the smallest Y following integer @@ -93,26 +95,57 @@ struct is_contained<T, std::tuple<U, Ts...>> : is_contained<T, std::tuple<Ts...> * * @return The bilinear interpolated pixel value */ -inline uint8_t delta_bilinear_c1u8(const uint8_t *pixel_ptr, size_t stride, float dx, float dy); +template <typename T> +inline T delta_bilinear_c1(const T *pixel_ptr, size_t stride, float dx, float dy) +{ + ARM_COMPUTE_ERROR_ON(pixel_ptr == nullptr); + + const float dx1 = 1.0f - dx; + const float dy1 = 1.0f - dy; + + const T a00 = *pixel_ptr; + const T a01 = *(pixel_ptr + 1); + const T a10 = *(pixel_ptr + stride); + const T a11 = *(pixel_ptr + stride + 1); + + const float w1 = dx1 * dy1; + const float w2 = dx * dy1; + const float w3 = dx1 * dy; + const float w4 = dx * dy; -/** Return the pixel at (x,y) using bilinear interpolation. The image must be single channel U8 + return static_cast<T>(a00 * w1 + a01 * w2 + a10 * w3 + a11 * w4); +} + +/** Return the pixel at (x,y) using bilinear interpolation. * * @warning Only works if the iterator was created with an IImage * - * @param[in] first_pixel_ptr Pointer to the first pixel of a single channel U8 image. + * @param[in] first_pixel_ptr Pointer to the first pixel of a single channel input. * @param[in] stride Stride in bytes of the image; * @param[in] x X position of the wanted pixel * @param[in] y Y position of the wanted pixel * * @return The pixel at (x, y) using bilinear interpolation. */ -inline uint8_t pixel_bilinear_c1u8(const uint8_t *first_pixel_ptr, size_t stride, float x, float y); +template <typename T> +inline T pixel_bilinear_c1(const T *first_pixel_ptr, size_t stride, float x, float y) +{ + ARM_COMPUTE_ERROR_ON(first_pixel_ptr == nullptr); + + const int32_t xi = std::floor(x); + const int32_t yi = std::floor(y); -/** Return the pixel at (x,y) using bilinear interpolation by clamping when out of borders. The image must be single channel U8 + const float dx = x - xi; + const float dy = y - yi; + + return delta_bilinear_c1(first_pixel_ptr + xi + yi * stride, stride, dx, dy); +} + +/** Return the pixel at (x,y) using bilinear interpolation by clamping when out of borders. The image must be single channel input * * @warning Only works if the iterator was created with an IImage * - * @param[in] first_pixel_ptr Pointer to the first pixel of a single channel U8 image. + * @param[in] first_pixel_ptr Pointer to the first pixel of a single channel image. * @param[in] stride Stride in bytes of the image * @param[in] width Width of the image * @param[in] height Height of the image @@ -121,7 +154,22 @@ inline uint8_t pixel_bilinear_c1u8(const uint8_t *first_pixel_ptr, size_t stride * * @return The pixel at (x, y) using bilinear interpolation. */ -inline uint8_t pixel_bilinear_c1u8_clamp(const uint8_t *first_pixel_ptr, size_t stride, size_t width, size_t height, float x, float y); +template <typename T> +inline uint8_t pixel_bilinear_c1_clamp(const T *first_pixel_ptr, size_t stride, size_t width, size_t height, float x, float y) +{ + ARM_COMPUTE_ERROR_ON(first_pixel_ptr == nullptr); + + x = std::max(-1.f, std::min(x, static_cast<float>(width))); + y = std::max(-1.f, std::min(y, static_cast<float>(height))); + + const float xi = std::floor(x); + const float yi = std::floor(y); + + const float dx = x - xi; + const float dy = y - yi; + + return delta_bilinear_c1(first_pixel_ptr + static_cast<int32_t>(xi) + static_cast<int32_t>(yi) * stride, stride, dx, dy); +} /** Return the pixel at (x,y) using area interpolation by clamping when out of borders. The image must be single channel U8 * |