aboutsummaryrefslogtreecommitdiff
path: root/arm_compute/core/Helpers.h
diff options
context:
space:
mode:
authorAnthony Barbier <anthony.barbier@arm.com>2017-12-12 22:08:59 +0000
committerAnthony Barbier <anthony.barbier@arm.com>2018-11-02 16:42:33 +0000
commit9a33b5411fed53e2fa339957b4c0b8e31e402968 (patch)
tree6ff34cab47eb73ca37e9bff40aa4257984937ffa /arm_compute/core/Helpers.h
parent0223a78ba43f0b106347108857d2f8cbfe857198 (diff)
downloadComputeLibrary-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>
Diffstat (limited to 'arm_compute/core/Helpers.h')
-rw-r--r--arm_compute/core/Helpers.h63
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);
}