Compute Library
 21.02
WarpPerspective.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2019 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
25 
26 #include "Utils.h"
27 #include "WarpPerspective.h"
28 
29 namespace arm_compute
30 {
31 namespace test
32 {
33 namespace validation
34 {
35 namespace reference
36 {
37 template <typename T>
38 SimpleTensor<T> warp_perspective(const SimpleTensor<T> &src, SimpleTensor<T> &valid_mask, const float *matrix, InterpolationPolicy policy, BorderMode border_mode, uint8_t constant_border_value)
39 {
40  SimpleTensor<T> dst(src.shape(), src.data_type());
41 
42  // x0 = M00 * x + M01 * y + M02
43  // y0 = M10 * x + M11 * y + M12
44  // z0 = M20 * x + M21 * y + M22
45  // xn = x0 / z0
46  // yn = y0 / z0
47  const float M00 = matrix[0];
48  const float M10 = matrix[1];
49  const float M20 = matrix[2];
50  const float M01 = matrix[0 + 1 * 3];
51  const float M11 = matrix[1 + 1 * 3];
52  const float M21 = matrix[2 + 1 * 3];
53  const float M02 = matrix[0 + 2 * 3];
54  const float M12 = matrix[1 + 2 * 3];
55  const float M22 = matrix[2 + 2 * 3];
56 
57  const int width = src.shape().x();
58  const int height = src.shape().y();
59 
60  const uint32_t num_elements = src.num_elements();
61  for(uint32_t element_idx = 0; element_idx < num_elements; ++element_idx)
62  {
63  valid_mask[element_idx] = 1;
64  Coordinates id = index2coord(src.shape(), element_idx);
65  const int idx = id.x();
66  const int idy = id.y();
67  const float z0 = M20 * idx + M21 * idy + M22;
68 
69  const float x0 = (M00 * idx + M01 * idy + M02);
70  const float y0 = (M10 * idx + M11 * idy + M12);
71 
72  const float xn = x0 / z0;
73  const float yn = y0 / z0;
74  id.set(0, static_cast<int>(std::floor(xn)));
75  id.set(1, static_cast<int>(std::floor(yn)));
76  if((0 <= yn) && (yn < height) && (0 <= xn) && (xn < width))
77  {
78  switch(policy)
79  {
81  dst[element_idx] = tensor_elem_at(src, id, border_mode, constant_border_value);
82  break;
84  (valid_bilinear_policy(xn, yn, width, height, border_mode)) ? dst[element_idx] = bilinear_policy(src, id, xn, yn, border_mode, constant_border_value) : valid_mask[element_idx] = 0;
85  break;
87  default:
88  ARM_COMPUTE_ERROR("Interpolation not supported");
89  break;
90  }
91  }
92  else
93  {
94  if(border_mode == BorderMode::UNDEFINED)
95  {
96  valid_mask[element_idx] = 0;
97  }
98  else
99  {
100  switch(policy)
101  {
103  if(border_mode == BorderMode::CONSTANT)
104  {
105  dst[element_idx] = constant_border_value;
106  }
107  else if(border_mode == BorderMode::REPLICATE)
108  {
109  id.set(0, std::max(0, std::min(static_cast<int>(xn), width - 1)));
110  id.set(1, std::max(0, std::min(static_cast<int>(yn), height - 1)));
111  dst[element_idx] = src[coord2index(src.shape(), id)];
112  }
113  break;
115  dst[element_idx] = bilinear_policy(src, id, xn, yn, border_mode, constant_border_value);
116  break;
118  default:
119  ARM_COMPUTE_ERROR("Interpolation not supported");
120  break;
121  }
122  }
123  }
124  }
125  return dst;
126 }
127 
128 template SimpleTensor<uint8_t> warp_perspective(const SimpleTensor<uint8_t> &src, SimpleTensor<uint8_t> &valid_mask, const float *matrix, InterpolationPolicy policy, BorderMode border_mode,
129  uint8_t constant_border_value);
130 } // namespace reference
131 } // namespace validation
132 } // namespace test
133 } // namespace arm_compute
BorderMode
Methods available to handle borders.
Definition: Types.h:265
InterpolationPolicy
Interpolation method.
Definition: Types.h:392
T tensor_elem_at(const SimpleTensor< T > &src, Coordinates coord, BorderMode border_mode, T constant_border_value)
Definition: Utils.h:64
SimpleTensor< T > warp_perspective(const SimpleTensor< T > &src, SimpleTensor< T > &valid_mask, const float *matrix, InterpolationPolicy policy, BorderMode border_mode, uint8_t constant_border_value)
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
Definition: Error.h:352
DataType data_type() const override
Data type of the tensor.
Definition: SimpleTensor.h:357
Output values are defined by bilinear interpolation between the pixels.
TensorShape shape() const override
Shape of the tensor.
Definition: SimpleTensor.h:320
Output values are defined to match the source pixel whose center is nearest to the sample position...
SimpleTensor< float > src
Definition: DFT.cpp:155
Copyright (c) 2017-2021 Arm Limited.
int coord2index(const TensorShape &shape, const Coordinates &coord)
Linearise the given coordinate.
Definition: Utils.h:489
T x() const
Alias to access the size of the first dimension.
Definition: Dimensions.h:87
Coordinates of an item.
Definition: Coordinates.h:37
T bilinear_policy(const SimpleTensor< T > &in, Coordinates id, float xn, float yn, BorderMode border_mode, T constant_border_value)
Definition: Utils.cpp:36
Coordinates index2coord(const TensorShape &shape, int index)
Convert a linear index into n-dimensional coordinates.
Definition: Utils.h:460
Output values are determined by averaging the source pixels whose areas fall under the area of the de...
Simple tensor object that stores elements in a consecutive chunk of memory.
Definition: SimpleTensor.h:58
Borders are left undefined.
Pixels outside the image are assumed to have the same value as the closest image pixel.
int num_elements() const override
Number of elements of the tensor.
Definition: SimpleTensor.h:406
bool valid_bilinear_policy(float xn, float yn, int width, int height, BorderMode border_mode)
Definition: WarpAffine.cpp:36