diff options
author | Anthony Barbier <anthony.barbier@arm.com> | 2017-12-12 22:08:59 +0000 |
---|---|---|
committer | Anthony Barbier <anthony.barbier@arm.com> | 2018-11-02 16:42:33 +0000 |
commit | 9a33b5411fed53e2fa339957b4c0b8e31e402968 (patch) | |
tree | 6ff34cab47eb73ca37e9bff40aa4257984937ffa | |
parent | 0223a78ba43f0b106347108857d2f8cbfe857198 (diff) | |
download | ComputeLibrary-9a33b5411fed53e2fa339957b4c0b8e31e402968.tar.gz |
COMPMID-745: Handle bilinear interpolation for remap differently
Until now if pixels coordinates were clamped to the padding, then the
bilinear interpolation would be performed using using 4 pixels out of
bounds, requiring 2 pixels in the right and bottom borders.
Instead now we skip the interpolation if it's not needed.
When using bilinear filtering + border mode constant: we need two pixels on the right and bottom for the interpolation
- Reverted to BorderSize(1)
- Handle special case differently in bilinear function
Change-Id: Ic431975cff236c048fa329644ae7b67d4476ab1e
Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/113016
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
Reviewed-by: Michalis Spyrou <michalis.spyrou@arm.com>
Tested-by: BSG Visual Compute Jenkins server to access repositories on http://mpd-gerrit.cambridge.arm.com <bsgcomp@arm.com>
-rw-r--r-- | arm_compute/core/Helpers.h | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/arm_compute/core/Helpers.h b/arm_compute/core/Helpers.h index fdbb46fc78..c02f14aecc 100644 --- a/arm_compute/core/Helpers.h +++ b/arm_compute/core/Helpers.h @@ -117,6 +117,57 @@ inline T delta_bilinear_c1(const T *pixel_ptr, size_t stride, float dx, float dy return static_cast<T>(a00 * w1 + a01 * w2 + a10 * w3 + a11 * w4); } +/** Computes linear interpolation using the pointer to the top pixel and the pixel's distance between + * the real coordinates and the smallest following integer coordinates. Input must be in single channel format. + * + * @param[in] pixel_ptr Pointer to the top pixel value of a single channel input. + * @param[in] stride Stride to access the bottom pixel value + * @param[in] dy Pixel's distance between the Y real coordinate and the smallest Y following integer + * + * @note dy must be in the range [0, 1.0] + * + * @return The linear interpolated pixel value + */ +template <typename T> +inline T delta_linear_c1_y(const T *pixel_ptr, size_t stride, float dy) +{ + ARM_COMPUTE_ERROR_ON(pixel_ptr == nullptr); + + const float dy1 = 1.0f - dy; + + const T a00 = *pixel_ptr; + const T a10 = *(pixel_ptr + stride); + + const float w1 = dy1; + const float w3 = dy; + + return static_cast<T>(a00 * w1 + a10 * w3); +} +/** Computes linear interpolation using the pointer to the left pixel and the pixel's distance between + * the real coordinates and the smallest following integer coordinates. Input must be in single channel format. + * + * @param[in] pixel_ptr Pointer to the left pixel value of a single channel input. + * @param[in] dx Pixel's distance between the X real coordinate and the smallest X following integer + * + * @note dx must be in the range [0, 1.0] + * + * @return The linear interpolated pixel value + */ +template <typename T> +inline T delta_linear_c1_x(const T *pixel_ptr, float dx) +{ + ARM_COMPUTE_ERROR_ON(pixel_ptr == nullptr); + + const T a00 = *pixel_ptr; + const T a01 = *(pixel_ptr + 1); + + const float dx1 = 1.0f - dx; + + const float w1 = dx1; + const float w2 = dx; + + return static_cast<T>(a00 * w1 + a01 * w2); +} /** Return the pixel at (x,y) using bilinear interpolation. * * @warning Only works if the iterator was created with an IImage @@ -169,6 +220,18 @@ inline uint8_t pixel_bilinear_c1_clamp(const T *first_pixel_ptr, size_t stride, const float dx = x - xi; const float dy = y - yi; + if(dx == 0.0f) + { + if(dy == 0.0f) + { + return static_cast<T>(first_pixel_ptr[static_cast<int32_t>(xi) + static_cast<int32_t>(yi) * stride]); + } + return delta_linear_c1_y(first_pixel_ptr + static_cast<int32_t>(xi) + static_cast<int32_t>(yi) * stride, stride, dy); + } + if(dy == 0.0f) + { + return delta_linear_c1_x(first_pixel_ptr + static_cast<int32_t>(xi) + static_cast<int32_t>(yi) * stride, dx); + } return delta_bilinear_c1(first_pixel_ptr + static_cast<int32_t>(xi) + static_cast<int32_t>(yi) * stride, stride, dx, dy); } |