21 inline float Lerp(
float a,
float b,
float w)
23 return w * b + (1.f - w) * a;
26 inline double EuclideanDistance(
float Xa,
float Ya,
const unsigned int Xb,
const unsigned int Yb)
28 return std::sqrt(pow(Xa - armnn::numeric_cast<float>(Xb), 2) + pow(Ya - armnn::numeric_cast<float>(Yb), 2));
31 inline float CalculateResizeScale(
const unsigned int& InputSize,
32 const unsigned int& OutputSize,
33 const bool& AlignCorners)
35 return (AlignCorners && OutputSize > 1)
36 ? armnn::numeric_cast<float>(InputSize - 1) / armnn::numeric_cast<float>(OutputSize - 1)
40 inline float PixelScaler(
const unsigned int& Pixel,
42 const bool& HalfPixelCenters,
48 return (
static_cast<float>(Pixel) + 0.5f) * Scale - 0.5f;
53 return (
static_cast<float>(Pixel) + 0.5f) * Scale;
57 return static_cast<float>(Pixel) * Scale;
72 bool halfPixelCenters)
81 const unsigned int batchSize = inputInfo.
GetShape()[0];
91 const float scaleY = CalculateResizeScale(inputHeight, outputHeight, alignCorners);
92 const float scaleX = CalculateResizeScale(inputWidth, outputWidth, alignCorners);
97 for (
unsigned int n = 0; n < batchSize; ++n)
99 for (
unsigned int c = 0; c < channelCount; ++c)
101 for (
unsigned int y = 0; y < outputHeight; ++y)
104 float iy = PixelScaler(y, scaleY, halfPixelCenters, resizeMethod);
107 const float fiy = (resizeMethod == ResizeMethod::NearestNeighbor && alignCorners) ?
armnn::roundf(iy)
110 const unsigned int y0 =
static_cast<unsigned int>(std::max(fiy, 0.0f));
113 const float yw = iy - fiy;
115 for (
unsigned int x = 0; x < outputWidth; ++x)
118 float ix = PixelScaler(x, scaleX, halfPixelCenters, resizeMethod);
121 const float fix = resizeMethod == ResizeMethod::NearestNeighbor && alignCorners ?
armnn::roundf(ix)
124 const unsigned int x0 =
static_cast<unsigned int>(std::max(fix, 0.0f));
127 const float xw = ix - fix;
132 if (halfPixelCenters)
134 x1 = std::min(
static_cast<unsigned int>(std::ceil(ix)), inputWidth - 1u);
135 y1 = std::min(
static_cast<unsigned int>(std::ceil(iy)), inputHeight - 1u);
140 x1 = std::min(x0 + 1, inputWidth - 1u);
141 y1 = std::min(y0 + 1, inputHeight - 1u);
144 float interpolatedValue;
145 switch (resizeMethod)
147 case ResizeMethod::Bilinear:
149 in[dataLayout.
GetIndex(inputShape, n, c, y0, x0)];
150 float input1 = in.
Get();
151 in[dataLayout.
GetIndex(inputShape, n, c, y0, x1)];
152 float input2 = in.
Get();
153 in[dataLayout.
GetIndex(inputShape, n, c, y1, x0)];
154 float input3 = in.
Get();
155 in[dataLayout.
GetIndex(inputShape, n, c, y1, x1)];
156 float input4 = in.
Get();
158 const float ly0 = Lerp(input1, input2, xw);
159 const float ly1 = Lerp(input3, input4, xw);
160 interpolatedValue = Lerp(ly0, ly1, yw);
163 case ResizeMethod::NearestNeighbor:
166 auto distance00 = EuclideanDistance(fix, fiy, x0, y0);
167 auto distance01 = EuclideanDistance(fix, fiy, x0, y1);
168 auto distance10 = EuclideanDistance(fix, fiy, x1, y0);
169 auto distance11 = EuclideanDistance(fix, fiy, x1, y1);
171 auto minimum = std::min( { distance00, distance01, distance10, distance11 } );
173 unsigned int xNearest = 0;
174 unsigned int yNearest = 0;
181 else if (
minimum == distance01)
186 else if (
minimum == distance10)
191 else if (
minimum == distance11)
201 in[dataLayout.
GetIndex(inputShape, n, c, yNearest, xNearest)];
202 interpolatedValue = in.
Get();
207 std::to_string(
static_cast<int>(resizeMethod)));
209 out[dataLayout.
GetIndex(outputShape, n, c, y, x)];
210 out.
Set(interpolatedValue);