arm_bilinear_interp_f16.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /* ----------------------------------------------------------------------
  2. * Project: CMSIS DSP Library
  3. * Title: arm_bilinear_interp_f16.c
  4. * Description: Floating-point bilinear interpolation
  5. *
  6. * $Date: 23 April 2021
  7. * $Revision: V1.9.0
  8. *
  9. * Target Processor: Cortex-M and Cortex-A cores
  10. * -------------------------------------------------------------------- */
  11. /*
  12. * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
  13. *
  14. * SPDX-License-Identifier: Apache-2.0
  15. *
  16. * Licensed under the Apache License, Version 2.0 (the License); you may
  17. * not use this file except in compliance with the License.
  18. * You may obtain a copy of the License at
  19. *
  20. * www.apache.org/licenses/LICENSE-2.0
  21. *
  22. * Unless required by applicable law or agreed to in writing, software
  23. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  24. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25. * See the License for the specific language governing permissions and
  26. * limitations under the License.
  27. */
  28. #include "dsp/interpolation_functions_f16.h"
  29. #if defined(ARM_FLOAT16_SUPPORTED)
  30. /**
  31. @ingroup groupInterpolation
  32. */
  33. /**
  34. * @defgroup BilinearInterpolate Bilinear Interpolation
  35. *
  36. * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid.
  37. * The underlying function <code>f(x, y)</code> is sampled on a regular grid and the interpolation process
  38. * determines values between the grid points.
  39. * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension.
  40. * Bilinear interpolation is often used in image processing to rescale images.
  41. * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types.
  42. *
  43. * <b>Algorithm</b>
  44. * \par
  45. * The instance structure used by the bilinear interpolation functions describes a two dimensional data table.
  46. * For floating-point, the instance structure is defined as:
  47. * <pre>
  48. * typedef struct
  49. * {
  50. * uint16_t numRows;
  51. * uint16_t numCols;
  52. * float16_t *pData;
  53. * } arm_bilinear_interp_instance_f16;
  54. * </pre>
  55. *
  56. * \par
  57. * where <code>numRows</code> specifies the number of rows in the table;
  58. * <code>numCols</code> specifies the number of columns in the table;
  59. * and <code>pData</code> points to an array of size <code>numRows*numCols</code> values.
  60. * The data table <code>pTable</code> is organized in row order and the supplied data values fall on integer indexes.
  61. * That is, table element (x,y) is located at <code>pTable[x + y*numCols]</code> where x and y are integers.
  62. *
  63. * \par
  64. * Let <code>(x, y)</code> specify the desired interpolation point. Then define:
  65. * <pre>
  66. * XF = floor(x)
  67. * YF = floor(y)
  68. * </pre>
  69. * \par
  70. * The interpolated output point is computed as:
  71. * <pre>
  72. * f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
  73. * + f(XF+1, YF) * (x-XF)*(1-(y-YF))
  74. * + f(XF, YF+1) * (1-(x-XF))*(y-YF)
  75. * + f(XF+1, YF+1) * (x-XF)*(y-YF)
  76. * </pre>
  77. * Note that the coordinates (x, y) contain integer and fractional components.
  78. * The integer components specify which portion of the table to use while the
  79. * fractional components control the interpolation processor.
  80. *
  81. * \par
  82. * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output.
  83. */
  84. /**
  85. * @addtogroup BilinearInterpolate
  86. * @{
  87. */
  88. /**
  89. * @brief Floating-point bilinear interpolation.
  90. * @param[in,out] S points to an instance of the interpolation structure.
  91. * @param[in] X interpolation coordinate.
  92. * @param[in] Y interpolation coordinate.
  93. * @return out interpolated value.
  94. */
  95. float16_t arm_bilinear_interp_f16(
  96. const arm_bilinear_interp_instance_f16 * S,
  97. float16_t X,
  98. float16_t Y)
  99. {
  100. float16_t out;
  101. float16_t f00, f01, f10, f11;
  102. float16_t *pData = S->pData;
  103. int32_t xIndex, yIndex, index;
  104. float16_t xdiff, ydiff;
  105. float16_t b1, b2, b3, b4;
  106. xIndex = (int32_t) X;
  107. yIndex = (int32_t) Y;
  108. /* Care taken for table outside boundary */
  109. /* Returns zero output when values are outside table boundary */
  110. if (xIndex < 0 || xIndex > (S->numCols - 2) || yIndex < 0 || yIndex > (S->numRows - 2))
  111. {
  112. return (0);
  113. }
  114. /* Calculation of index for two nearest points in X-direction */
  115. index = (xIndex ) + (yIndex ) * S->numCols;
  116. /* Read two nearest points in X-direction */
  117. f00 = pData[index];
  118. f01 = pData[index + 1];
  119. /* Calculation of index for two nearest points in Y-direction */
  120. index = (xIndex ) + (yIndex+1) * S->numCols;
  121. /* Read two nearest points in Y-direction */
  122. f10 = pData[index];
  123. f11 = pData[index + 1];
  124. /* Calculation of intermediate values */
  125. b1 = f00;
  126. b2 = (_Float16)f01 - (_Float16)f00;
  127. b3 = (_Float16)f10 - (_Float16)f00;
  128. b4 = (_Float16)f00 - (_Float16)f01 - (_Float16)f10 + (_Float16)f11;
  129. /* Calculation of fractional part in X */
  130. xdiff = (_Float16)X - (_Float16)xIndex;
  131. /* Calculation of fractional part in Y */
  132. ydiff = (_Float16)Y - (_Float16)yIndex;
  133. /* Calculation of bi-linear interpolated output */
  134. out = (_Float16)b1 + (_Float16)b2 * (_Float16)xdiff +
  135. (_Float16)b3 * (_Float16)ydiff + (_Float16)b4 * (_Float16)xdiff * (_Float16)ydiff;
  136. /* return to application */
  137. return (out);
  138. }
  139. /**
  140. * @} end of BilinearInterpolate group
  141. */
  142. #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */