MCPcopy Create free account
hub / github.com/arrayfire/arrayfire / buildGaussPyr

Function buildGaussPyr

src/backend/cuda/kernel/sift.hpp:1018–1076  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1016
1017template<typename T, typename convAccT>
1018std::vector<Array<T>> buildGaussPyr(Param<T> init_img, const unsigned n_octaves,
1019 const unsigned n_layers,
1020 const float init_sigma) {
1021 // Precompute Gaussian sigmas using the following formula:
1022 // \sigma_{total}^2 = \sigma_{i}^2 + \sigma_{i-1}^2
1023 std::vector<float> sig_layers(n_layers + 3);
1024 sig_layers[0] = init_sigma;
1025 float k = std::pow(2.0f, 1.0f / n_layers);
1026 for (unsigned i = 1; i < n_layers + 3; i++) {
1027 float sig_prev = std::pow(k, i - 1) * init_sigma;
1028 float sig_total = sig_prev * k;
1029 sig_layers[i] = std::sqrt(sig_total * sig_total - sig_prev * sig_prev);
1030 }
1031
1032 // Gaussian Pyramid
1033 std::vector<Array<T>> gauss_pyr;
1034 std::vector<Array<T>> tmp_pyr;
1035 gauss_pyr.reserve(n_octaves);
1036 tmp_pyr.reserve(n_octaves * (n_layers + 3));
1037 for (unsigned o = 0; o < n_octaves; o++) {
1038 gauss_pyr.push_back(createEmptyArray<T>(
1039 {(o == 0) ? init_img.dims[0] : gauss_pyr[o - 1].dims()[0] / 2,
1040 (o == 0) ? init_img.dims[1] : gauss_pyr[o - 1].dims()[1] / 2,
1041 n_layers + 3}));
1042
1043 for (unsigned l = 0; l < n_layers + 3; l++) {
1044 unsigned src_idx = (l == 0) ? (o - 1) * (n_layers + 3) + n_layers
1045 : o * (n_layers + 3) + l - 1;
1046 unsigned idx = o * (n_layers + 3) + l;
1047
1048 if (o == 0 && l == 0) {
1049 tmp_pyr.push_back(createParamArray(init_img, false));
1050 } else if (l == 0) {
1051 tmp_pyr.push_back(
1052 createEmptyArray<T>({tmp_pyr[src_idx].dims()[0] / 2,
1053 tmp_pyr[src_idx].dims()[1] / 2}));
1054 resize<T>(tmp_pyr[idx], tmp_pyr[src_idx], AF_INTERP_BILINEAR);
1055 } else {
1056 tmp_pyr.push_back(createEmptyArray<T>(tmp_pyr[src_idx].dims()));
1057 Array<T> tmp = createEmptyArray<T>(tmp_pyr[src_idx].dims());
1058 Array<convAccT> filter = gauss_filter<convAccT>(sig_layers[l]);
1059
1060 convolve2<T, convAccT>(tmp, tmp_pyr[src_idx], filter, 0, false);
1061 convolve2<T, convAccT>(tmp_pyr[idx], CParam<T>(tmp), filter, 1,
1062 false);
1063
1064 // memFree(tmp.ptr);
1065 }
1066
1067 const unsigned imel = tmp_pyr[idx].elements();
1068 const unsigned offset = imel * l;
1069
1070 CUDA_CHECK(cudaMemcpyAsync(
1071 gauss_pyr[o].get() + offset, tmp_pyr[idx].get(),
1072 imel * sizeof(T), cudaMemcpyDeviceToDevice, getActiveStream()));
1073 }
1074 }
1075 return gauss_pyr;

Callers

nothing calls this directly

Calls 7

powFunction · 0.85
sqrtFunction · 0.85
getActiveStreamFunction · 0.85
createParamArrayFunction · 0.50
dimsMethod · 0.45
elementsMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected