ImagePyramid<T> gaussian_pyramid(const ImageView<T>& image, const ImagePyramidParams& params = ImagePyramidParams()) { using Scalar = typename ImagePyramid<T>::scalar_type; // Resize the image with the appropriate factor. auto resize_factor = pow(2.f, -params.first_octave_index()); auto I = enlarge(image, resize_factor); // Deduce the new camera sigma with respect to the dilated image. auto camera_sigma = Scalar(params.scale_camera())*resize_factor; // Blur the image so that its new sigma is equal to the initial sigma. auto init_sigma = Scalar(params.scale_initial()); if (camera_sigma < init_sigma) { Scalar sigma = sqrt(init_sigma*init_sigma - camera_sigma*camera_sigma); I = gaussian(I, sigma); } // Deduce the maximum number of octaves. auto l = std::min(image.width(), image.height()); auto b = params.image_padding_size(); // l/2^k > 2b // 2^k < l/(2b) // k < log(l/(2b))/log(2) auto num_octaves = static_cast<int>(log(l/(2.f*b))/log(2.f)); // Shorten names. auto k = Scalar(params.scale_geometric_factor()); auto num_scales = params.num_scales_per_octave(); auto downscale_index = int( floor( log(Scalar(2))/log(k)) ); // Create the image pyramid auto G = ImagePyramid<T>{}; G.reset(num_octaves, num_scales, init_sigma, k); for (auto o = 0; o < num_octaves; ++o) { // Compute the octave scaling factor G.octave_scaling_factor(o) = (o == 0) ? 1.f/resize_factor : G.octave_scaling_factor(o-1)*2; // Compute the gaussians in octave \f$o\f$ Scalar sigma_s_1 = init_sigma; G(0, o) = o == 0 ? I : downscale(G(downscale_index, o - 1), 2); for (auto s = 1; s < num_scales; ++s) { auto sigma = sqrt(k*k*sigma_s_1*sigma_s_1 - sigma_s_1*sigma_s_1); G(s,o) = gaussian(G(s-1,o), sigma); sigma_s_1 *= k; } } // Done! return G; }
/*! @brief Constructor @param[in] extremum_thres the response threshold which local maxima of the determinant of Hessian function must satisfy. @param[in] img_padding_sz This variable indicates the minimum border size of the image. Maxima of determinant of Hessians located in the border of width 'img_padding_sz' are discarded. @param[in] numScales This variable indicates the number of scales to search in order to select the characteristic scale of a corner. @param[in] extremumRefinementIter This variable controls the number of iterations to refine the localization of DoG extrema in scale-space. The refinement process is based on the function **DO::refineExtremum()**. */ ComputeHessianLaplaceMaxima(const ImagePyramidParams& pyrParams = ImagePyramidParams(-1, 3+1), float extremum_thres = 1e-5f, int img_padding_sz = 1, int numScales = 10, int extremumRefinementIter = 5) : _pyr_params(pyrParams) , _extremum_thres(extremum_thres) , _img_padding_sz(img_padding_sz) , _extremum_refinement_iter(extremumRefinementIter) , _num_scales(numScales) { }