| 187 | |
| 188 | template<typename T> |
| 189 | void centroid_angle(const float* x_in, const float* y_in, |
| 190 | float* orientation_out, const unsigned total_feat, |
| 191 | CParam<T> image, const unsigned patch_size) { |
| 192 | const af::dim4 idims = image.dims(); |
| 193 | const T* image_ptr = image.get(); |
| 194 | for (unsigned f = 0; f < total_feat; f++) { |
| 195 | unsigned x = (unsigned)round(x_in[f]); |
| 196 | unsigned y = (unsigned)round(y_in[f]); |
| 197 | |
| 198 | unsigned r = patch_size / 2; |
| 199 | if (x < r || y < r || x > idims[1] - r || y > idims[0] - r) continue; |
| 200 | |
| 201 | T m01 = (T)0, m10 = (T)0; |
| 202 | unsigned patch_size_sq = patch_size * patch_size; |
| 203 | for (unsigned k = 0; k < patch_size_sq; k++) { |
| 204 | int i = k / patch_size - r; |
| 205 | int j = k % patch_size - r; |
| 206 | |
| 207 | // Calculate first order moments |
| 208 | T p = image_ptr[(x + i) * idims[0] + y + j]; |
| 209 | m01 += j * p; |
| 210 | m10 += i * p; |
| 211 | } |
| 212 | |
| 213 | float angle = atan2(m01, m10); |
| 214 | orientation_out[f] = angle; |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | template<typename T> |
| 219 | inline T get_pixel(unsigned x, unsigned y, const float ori, const unsigned size, |