diff --git a/include/boost/gil/detail/math.hpp b/include/boost/gil/detail/math.hpp index 934f11ac82..83212e240a 100644 --- a/include/boost/gil/detail/math.hpp +++ b/include/boost/gil/detail/math.hpp @@ -1,5 +1,6 @@ // // Copyright 2019 Olzhas Zhumabek +// Copyright 2021 Prathamesh Tagore // // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -8,17 +9,36 @@ #ifndef BOOST_GIL_IMAGE_PROCESSING_DETAIL_MATH_HPP #define BOOST_GIL_IMAGE_PROCESSING_DETAIL_MATH_HPP -#include #include +#include +#include +#include namespace boost { namespace gil { namespace detail { +enum class kernel_type +{ + sobel_dx, + sobel_dy, +}; + static constexpr double pi = 3.14159265358979323846; static constexpr std::array dx_sobel = {{-1, 0, 1, -2, 0, 2, -1, 0, 1}}; +static constexpr std::array dx_sobel2 = {{ + -1,-2,0,2,1,-4,-8,0,8,4,-6,-12,0,12,6,-4,-8,0,8,4,-1,-2,0,2,1 +}}; +// In variable name "dx_sobel2", "2" indicates that the order of Sobel derivative in x-direction +// is 2. static constexpr std::array dx_scharr = {{-1, 0, 1, -1, 0, 1, -1, 0, 1}}; static constexpr std::array dy_sobel = {{1, 2, 1, 0, 0, 0, -1, -2, -1}}; +static constexpr std::array dy_sobel2 = {{ + -1,-4,-6,-4,-1,-2,-8,-12,-8,-2,0,0,0,0,0,2,8,12,8,2,1,4,6,4,1 +}}; +// In variable name "dy_sobel2", "2" indicates that the order of Sobel derivative in y-direction +// is 2. static constexpr std::array dy_scharr = {{1, 1, 1, 0, 0, 0, -1, -1, -1}}; +static const std::vector> smoothing_kernel {{1,2,1},{2,4,2},{1,2,1}}; template inline detail::kernel_2d get_identity_kernel() @@ -28,6 +48,164 @@ inline detail::kernel_2d get_identity_kernel() return kernel; } -}}} // namespace boost::gil::detail +// Please refer https://stackoverflow.com/a/10032882/14958679 for getting an overview of the +// concept applied for obtaining higher order Sobel kernels. + +/// \defgroup KernelGeneration +/// \brief Contains documentation for functions used in kernel generation. +/// +/// Separate functions are used for generating only those kernels whose dimensions are greater than +/// 5x5. Smaller kernels are fed directly to the algorithm. +/// + +/// \addtogroup KernelGeneration +/// @{ +/// \brief Produces higher order kernel vector by performing discrete convolution between lower +/// order kernel vector and a smoothing kernel vector(kernel used for suppressing noise). +/// \param kernel1 - First argument for kernel vector convolution. +/// \param kernel2 - Second argument for kernel vector convolution. +/// \tparam T1 - Type of first argument for kernel vector convolution. +/// \tparam T2 - Type of second argument for kernel vector convolution. +template +inline auto kernel_convolve_impl(T1 kernel1, T2 kernel2) -> std::vector> +{ + std::ptrdiff_t convolved_kernel_size = kernel1.size() + kernel2.size() - 1; + std::vector> convolved_kernel(convolved_kernel_size, + std::vector(convolved_kernel_size)); + std::vector> dummy_kernel(convolved_kernel_size, + std::vector(convolved_kernel_size)); + + // 'dummy_kernel' will be made by padding 'kernel1' with appropriate no. of rows and columns + // containing zeros to match the size specified by 'convolved_kernel_size'. + + // 'convolved kernel' will store the result obtained after applying convolution between + // 'dummy_kernel' and 'kernel2'. + + // 'padding_origin' will be used for determining indices of blocks from where padding begins + // inside 'dummy_kernel'. It will be used for applying appropriate padding with zeros around + // 'kernel1' to create 'dummy_kernel'. + + std::ptrdiff_t padding_origin = (kernel2.size() - 1) / 2; + for (std::ptrdiff_t row = padding_origin; + row < static_cast(dummy_kernel.size()) - padding_origin; ++row) + { + for (std::ptrdiff_t col = padding_origin; + col < static_cast(dummy_kernel.size()) - padding_origin; ++col) + { + dummy_kernel[row][col] = kernel1[row - padding_origin][col - padding_origin]; + } + } + + std::ptrdiff_t flip_kernel_row, flip_kernel_col, row_boundary, col_boundary; + float aux_total = 0.0f; + for (std::ptrdiff_t dummy_row = 0; dummy_row < convolved_kernel_size; ++dummy_row) + { + for (std::ptrdiff_t dummy_col = 0; dummy_col < convolved_kernel_size; ++dummy_col) + { + aux_total = 0.0f; + for (std::ptrdiff_t kernel2_row = 0; + kernel2_row < static_cast(kernel2.size()); ++kernel2_row) + { + flip_kernel_row = kernel2.size() - 1 - kernel2_row; + for (std::ptrdiff_t kernel2_col = 0; + kernel2_col < static_cast(kernel2.size()); ++kernel2_col) + { + flip_kernel_col = kernel2.size() - 1 - kernel2_col; + row_boundary = dummy_row + kernel2.size()/2 - flip_kernel_row; + col_boundary = dummy_col + kernel2.size()/2 - flip_kernel_col; + + // ignore input samples which are out of bound + if (row_boundary >= 0 && row_boundary < convolved_kernel_size && + col_boundary >= 0 && col_boundary < convolved_kernel_size) + { + aux_total += + kernel2[flip_kernel_row][flip_kernel_col] * + dummy_kernel[row_boundary][col_boundary]; + } + } + } + convolved_kernel[dummy_row][dummy_col] = aux_total; + } + } + return convolved_kernel; +} + +/// \brief Fills kernel vector given as argument with a second order kernel in horizontal or +/// vertical direction. The type of the kernel which is to be used for filling will be indicated +/// by the variable 'type'. +/// \param kernel - Kernel vector which will be filled. +/// \param type - Indicates the type of second order derivative kernel which is to be filled inside +/// first argument. +inline void kernel_vector_fill(std::vector>& kernel, kernel_type type) +{ + if (type == kernel_type::sobel_dx) + { + for (std::ptrdiff_t row = 0; row < 5; ++row) + { + for (std::ptrdiff_t col = 0; col < 5; ++col) + { + kernel[row][col] = dx_sobel2[5 * row + col]; + } + } + } + else if (type == kernel_type::sobel_dy) + { + for (std::ptrdiff_t row =0; row < 5; ++row) + { + for (std::ptrdiff_t col = 0; col < 5; ++col) + { + kernel[row][col] = dy_sobel2[5 * row + col]; + } + } + } +} + +/// \brief Passes parameters to 'kernel_convolve_impl()' repeatedly until kernel vector of desired +/// order is obtained. +/// \param order - Indicates order of derivative whose kernel vector is to be returned. +/// \param type - Indicates the type of kernel vector which is to be returned. +inline auto kernel_convolve(unsigned int order, kernel_type type) -> std::vector +{ + std::vector convolved_kernel_flatten; + std::vector> convolved_kernel(5, std::vector(5)); + + kernel_vector_fill(convolved_kernel, type); + + std::vector> smoothing_dummy = smoothing_kernel; + + // Variable 'smooth_repetition' will store the number of times we need to convolve + // 'smoothing_dummy' with itself. This number when used as a power of 2 in its exponentiation, + // will result in a number which is the largest power of 2 smaller than 'order - 2'. + double const smooth_repetition = static_cast(std::log2(order - 2)); + + for (unsigned int i = 0; i < smooth_repetition; ++i) + { + smoothing_dummy = kernel_convolve_impl(smoothing_dummy, smoothing_dummy); + } + + convolved_kernel = kernel_convolve_impl(convolved_kernel, smoothing_dummy); + + // Variable 'order_decrease' will store the amount of decrease in order obtained due to the above + // optimization. It stores the largest power of 2 smaller than 'order - 2'. + double const order_decrease = std::pow(2, smooth_repetition); + for (unsigned int i = 0; i < order - 2 - order_decrease; ++i) + { + convolved_kernel = kernel_convolve_impl(convolved_kernel, smoothing_kernel); + } + + for (std::ptrdiff_t row = 0; row < static_cast(convolved_kernel.size()); ++row) + { + for (std::ptrdiff_t col = 0; col < static_cast(convolved_kernel.size()); + ++col) + { + convolved_kernel_flatten.push_back(convolved_kernel[row][col]); + } + } + + return convolved_kernel_flatten; +} +/// @} +}}} // namespace boost::gil::detail + #endif diff --git a/include/boost/gil/image_processing/numeric.hpp b/include/boost/gil/image_processing/numeric.hpp index b601b17dd0..a5384251ff 100644 --- a/include/boost/gil/image_processing/numeric.hpp +++ b/include/boost/gil/image_processing/numeric.hpp @@ -1,5 +1,6 @@ // // Copyright 2019 Olzhas Zhumabek +// Copyright 2021 Prathamesh Tagore // // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -16,6 +17,7 @@ // fixes ambigious call to std::abs, https://stackoverflow.com/a/30084734/4593721 #include #include +#include namespace boost { namespace gil { @@ -161,24 +163,30 @@ inline detail::kernel_2d generate_gaussian_kernel(std::size_t side template > inline detail::kernel_2d generate_dx_sobel(unsigned int degree = 1) { - switch (degree) + if (degree == 0) + return detail::get_identity_kernel(); + else if (degree == 1) { - case 0: - { - return detail::get_identity_kernel(); - } - case 1: - { - detail::kernel_2d result(3, 1, 1); - std::copy(detail::dx_sobel.begin(), detail::dx_sobel.end(), result.begin()); - return result; - } - default: - throw std::logic_error("not supported yet"); + detail::kernel_2d result(3, 1, 1); + std::copy(detail::dx_sobel.begin(), detail::dx_sobel.end(), result.begin()); + return result; } - - //to not upset compiler - throw std::runtime_error("unreachable statement"); + else if (degree == 2) + { + detail::kernel_2d result(5, 2, 2); + std::copy(detail::dx_sobel2.begin(), detail::dx_sobel2.end(), result.begin()); + return result; + } + else if (degree <= 15) + { + detail::kernel_2d result(2 * degree + 1, degree, degree); + std::vector dx_sobeln = detail::kernel_convolve(degree, detail::kernel_type::sobel_dx); + std::copy(dx_sobeln.begin(), dx_sobeln.end(), result.begin()); + return result; + } + else + throw std::length_error("Larger kernels than 31x31 may fail/delay other executions, hence " + "they are not yet provided"); } /// \brief Generate Scharr operator in horizontal direction @@ -221,24 +229,30 @@ inline detail::kernel_2d generate_dx_scharr(unsigned int degree = template > inline detail::kernel_2d generate_dy_sobel(unsigned int degree = 1) { - switch (degree) + if (degree == 0) + return detail::get_identity_kernel(); + else if (degree == 1) { - case 0: - { - return detail::get_identity_kernel(); - } - case 1: - { - detail::kernel_2d result(3, 1, 1); - std::copy(detail::dy_sobel.begin(), detail::dy_sobel.end(), result.begin()); - return result; - } - default: - throw std::logic_error("not supported yet"); + detail::kernel_2d result(3, 1, 1); + std::copy(detail::dy_sobel.begin(), detail::dy_sobel.end(), result.begin()); + return result; } - - //to not upset compiler - throw std::runtime_error("unreachable statement"); + else if (degree == 2) + { + detail::kernel_2d result(5, 2, 2); + std::copy(detail::dy_sobel2.begin(), detail::dy_sobel2.end(), result.begin()); + return result; + } + else if (degree <= 15) + { + detail::kernel_2d result(2 * degree + 1, degree, degree); + std::vector dy_sobeln = detail::kernel_convolve(degree, detail::kernel_type::sobel_dy); + std::copy(dy_sobeln.begin(), dy_sobeln.end(), result.begin()); + return result; + } + else + throw std::length_error("Larger kernels than 31x31 may fail/delay other executions, hence " + "they are not yet provided"); } /// \brief Generate Scharr operator in vertical direction diff --git a/test/core/image_processing/sobel_scharr.cpp b/test/core/image_processing/sobel_scharr.cpp index 6ebc90cad6..23a82d5844 100644 --- a/test/core/image_processing/sobel_scharr.cpp +++ b/test/core/image_processing/sobel_scharr.cpp @@ -1,5 +1,6 @@ // // Copyright 2019 Olzhas Zhumabek +// Copyright 2021 Prathamesh Tagore // // Use, modification and distribution are subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -16,10 +17,215 @@ namespace gil = boost::gil; +// Following vectors are reference kernel vectors obtained from opencv squeezed in to one dimension. +// Number written after "dx_sobel" represents the order of derivative used. +// Ex. : "2" in "dx_sobel2" signifies that "dx_sobel2" contains refernce kernel for second order +// sobel derivative,"dx" signifies that the derivative is for horizontal direction. +std::vector dx_sobel2 {{ + -1,-2,0,2,1,-4,-8,0,8,4,-6,-12,0,12,6,-4,-8,0,8,4,-1,-2,0,2,1 +}}; + +std::vector dx_sobel3 { + -1, -4, -5, 0, 5, 4, 1, + -6, -24, -30, 0, 30, 24, 6, + -15, -60, -75, 0, 75, 60, 15, + -20, -80, -100, 0, 100, 80, 20, + -15, -60, -75, 0, 75, 60, 15, + -6, -24, -30, 0, 30, 24, 6, + -1, -4, -5, 0, 5, 4, 1 +}; + +std::vector dx_sobel4 { + -1, -6, -14, -14, 0, 14, 14, 6, 1, + -8, -48, -112, -112, 0, 112, 112, 48, 8, + -28, -168, -392, -392, 0, 392, 392, 168, 28, + -56, -336, -784, -784, 0, 784, 784, 336, 56, + -70, -420, -980, -980, 0, 980, 980, 420, 70, + -56, -336, -784, -784, 0, 784, 784, 336, 56, + -28, -168, -392, -392, 0, 392, 392, 168, 28, + -8, -48, -112, -112, 0, 112, 112, 48, 8, + -1, -6, -14, -14, 0, 14, 14, 6, 1 +}; + +std::vector dx_sobel5 { + -1.0000e+00, -8.0000e+00, -2.7000e+01, -4.8000e+01, -4.2000e+01, 0.0000e+00, + 4.2000e+01, 4.8000e+01, 2.7000e+01, 8.0000e+00, 1.0000e+00, + -1.0000e+01, -8.0000e+01, -2.7000e+02, -4.8000e+02, -4.2000e+02, 0.0000e+00, + 4.2000e+02, 4.8000e+02, 2.7000e+02, 8.0000e+01, 1.0000e+01, + -4.5000e+01, -3.6000e+02, -1.2150e+03, -2.1600e+03, -1.8900e+03, 0.0000e+00, + 1.8900e+03, 2.1600e+03, 1.2150e+03, 3.6000e+02, 4.5000e+01, + -1.2000e+02, -9.6000e+02, -3.2400e+03, -5.7600e+03, -5.0400e+03, 0.0000e+00, + 5.0400e+03, 5.7600e+03, 3.2400e+03, 9.6000e+02, 1.2000e+02, + -2.1000e+02, -1.6800e+03, -5.6700e+03, -1.0080e+04, -8.8200e+03, 0.0000e+00, + 8.8200e+03, 1.0080e+04, 5.6700e+03, 1.6800e+03, 2.1000e+02, + -2.5200e+02, -2.0160e+03, -6.8040e+03, -1.2096e+04, -1.0584e+04, 0.0000e+00, + 1.0584e+04, 1.2096e+04, 6.8040e+03, 2.0160e+03, 2.5200e+02, + -2.1000e+02, -1.6800e+03, -5.6700e+03, -1.0080e+04, -8.8200e+03, 0.0000e+00, + 8.8200e+03, 1.0080e+04, 5.6700e+03, 1.6800e+03, 2.1000e+02, + -1.2000e+02, -9.6000e+02, -3.2400e+03, -5.7600e+03, -5.0400e+03, 0.0000e+00, + 5.0400e+03, 5.7600e+03, 3.2400e+03, 9.6000e+02, 1.2000e+02, + -4.5000e+01, -3.6000e+02, -1.2150e+03, -2.1600e+03, -1.8900e+03, 0.0000e+00, + 1.8900e+03, 2.1600e+03, 1.2150e+03, 3.6000e+02, 4.5000e+01, + -1.0000e+01, -8.0000e+01, -2.7000e+02, -4.8000e+02, -4.2000e+02, 0.0000e+00, + 4.2000e+02, 4.8000e+02, 2.7000e+02, 8.0000e+01, 1.0000e+01, + -1.0000e+00, -8.0000e+00, -2.7000e+01, -4.8000e+01, -4.2000e+01, 0.0000e+00, + 4.2000e+01, 4.8000e+01, 2.7000e+01, 8.0000e+00, 1.0000e+00 +}; + +std::vector dx_sobel6 { + -1.00000e+00, -1.00000e+01, -4.40000e+01, -1.10000e+02, -1.65000e+02, + -1.32000e+02, 0.00000e+00, 1.32000e+02, 1.65000e+02, 1.10000e+02, + 4.40000e+01, 1.00000e+01, 1.00000e+00, + -1.20000e+01, -1.20000e+02, -5.28000e+02, -1.32000e+03, -1.98000e+03, + -1.58400e+03, 0.00000e+00, 1.58400e+03, 1.98000e+03, 1.32000e+03, + 5.28000e+02, 1.20000e+02, 1.20000e+01, + -6.60000e+01, -6.60000e+02, -2.90400e+03, -7.26000e+03, -1.08900e+04, + -8.71200e+03, 0.00000e+00, 8.71200e+03, 1.08900e+04, 7.26000e+03, + 2.90400e+03, 6.60000e+02, 6.60000e+01, + -2.20000e+02, -2.20000e+03, -9.68000e+03, -2.42000e+04, -3.63000e+04, + -2.90400e+04, 0.00000e+00, 2.90400e+04, 3.63000e+04, 2.42000e+04, + 9.68000e+03, 2.20000e+03, 2.20000e+02, + -4.95000e+02, -4.95000e+03, -2.17800e+04, -5.44500e+04, -8.16750e+04, + -6.53400e+04, 0.00000e+00, 6.53400e+04, 8.16750e+04, 5.44500e+04, + 2.17800e+04, 4.95000e+03, 4.95000e+02, + -7.92000e+02, -7.92000e+03, -3.48480e+04, -8.71200e+04, -1.30680e+05, + -1.04544e+05, 0.00000e+00, 1.04544e+05, 1.30680e+05, 8.71200e+04, + 3.48480e+04, 7.92000e+03, 7.92000e+02, + -9.24000e+02, -9.24000e+03, -4.06560e+04, -1.01640e+05, -1.52460e+05, + -1.21968e+05, 0.00000e+00, 1.21968e+05, 1.52460e+05, 1.01640e+05, + 4.06560e+04, 9.24000e+03, 9.24000e+02, + -7.92000e+02, -7.92000e+03, -3.48480e+04, -8.71200e+04, -1.30680e+05, + -1.04544e+05, 0.00000e+00, 1.04544e+05, 1.30680e+05, 8.71200e+04, + 3.48480e+04, 7.92000e+03, 7.92000e+02, + -4.95000e+02, -4.95000e+03, -2.17800e+04 ,-5.44500e+04, -8.16750e+04, + -6.53400e+04, 0.00000e+00, 6.53400e+04, 8.16750e+04, 5.44500e+04, + 2.17800e+04, 4.95000e+03, 4.95000e+02, + -2.20000e+02, -2.20000e+03, -9.68000e+03, -2.42000e+04, -3.63000e+04, + -2.90400e+04, 0.00000e+00, 2.90400e+04, 3.63000e+04, 2.42000e+04, + 9.68000e+03, 2.20000e+03, 2.20000e+02, + -6.60000e+01, -6.60000e+02, -2.90400e+03, -7.26000e+03, -1.08900e+04, + -8.71200e+03, 0.00000e+00, 8.71200e+03, 1.08900e+04, 7.26000e+03, + 2.90400e+03, 6.60000e+02, 6.60000e+01, + -1.20000e+01, -1.20000e+02, -5.28000e+02, -1.32000e+03, -1.98000e+03, + -1.58400e+03, 0.00000e+00, 1.58400e+03, 1.98000e+03, 1.32000e+03, + 5.28000e+02, 1.20000e+02, 1.20000e+01, + -1.00000e+00, -1.00000e+01, -4.40000e+01, -1.10000e+02, -1.65000e+02, + -1.32000e+02, 0.00000e+00, 1.32000e+02, 1.65000e+02 , 1.10000e+02, + 4.40000e+01, 1.00000e+01, 1.00000e+00 +}; + +std::vector dy_sobel2 {{ + -1,-4,-6,-4,-1,-2,-8,-12,-8,-2,0,0,0,0,0,2,8,12,8,2,1,4,6,4,1 +}}; + +std::vector dy_sobel3 { + -1, -6, -15, -20, -15, -6, -1, + -4, -24, -60, -80, -60, -24, -4, + -5, -30, -75, -100, -75, -30, -5, + 0, 0, 0, 0, 0, 0, 0, + 5, 30, 75, 100, 75, 30, 5, + 4, 24, 60, 80, 60, 24, 4, + 1, 6, 15, 20, 15, 6, 1 +}; + +std::vector dy_sobel4 { + -1, -8, -28, -56, -70, -56, -28, -8, -1, + -6, -48, -168, -336, -420, -336, -168, -48, -6, + -14, -112, -392, -784, -980, -784, -392, -112, -14, + -14, -112, -392, -784, -980, -784, -392, -112, -14, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 14, 112, 392, 784, 980, 784, 392, 112, 14, + 14, 112, 392, 784, 980, 784, 392, 112, 14, + 6, 48, 168, 336, 420, 336, 168, 48, 6, + 1, 8, 28, 56, 70, 56, 28, 8, 1 +}; + +std::vector dy_sobel5 { + -1.0000e+00, -1.0000e+01, -4.5000e+01, -1.2000e+02, -2.1000e+02, -2.5200e+02, + -2.1000e+02, -1.2000e+02, -4.5000e+01, -1.0000e+01, -1.0000e+00, + -8.0000e+00, -8.0000e+01, -3.6000e+02, -9.6000e+02, -1.6800e+03, -2.0160e+03, + -1.6800e+03, -9.6000e+02, -3.6000e+02, -8.0000e+01, -8.0000e+00, + -2.7000e+01, -2.7000e+02, -1.2150e+03, -3.2400e+03, -5.6700e+03, -6.8040e+03, + -5.6700e+03, -3.2400e+03, -1.2150e+03, -2.7000e+02, -2.7000e+01, + -4.8000e+01, -4.8000e+02, -2.1600e+03, -5.7600e+03, -1.0080e+04, -1.2096e+04, + -1.0080e+04, -5.7600e+03, -2.1600e+03, -4.8000e+02, -4.8000e+01, + -4.2000e+01, -4.2000e+02, -1.8900e+03, -5.0400e+03, -8.8200e+03, -1.0584e+04, + -8.8200e+03, -5.0400e+03, -1.8900e+03, -4.2000e+02, -4.2000e+01, + 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, + 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, + 4.2000e+01, 4.2000e+02, 1.8900e+03, 5.0400e+03, 8.8200e+03, 1.0584e+04, + 8.8200e+03, 5.0400e+03, 1.8900e+03, 4.2000e+02, 4.2000e+01, + 4.8000e+01, 4.8000e+02, 2.1600e+03, 5.7600e+03, 1.0080e+04, 1.2096e+04, + 1.0080e+04, 5.7600e+03, 2.1600e+03, 4.8000e+02, 4.8000e+01, + 2.7000e+01, 2.7000e+02, 1.2150e+03, 3.2400e+03, 5.6700e+03, 6.8040e+03, + 5.6700e+03, 3.2400e+03, 1.2150e+03, 2.7000e+02, 2.7000e+01, + 8.0000e+00, 8.0000e+01, 3.6000e+02, 9.6000e+02, 1.6800e+03, 2.0160e+03, + 1.6800e+03, 9.6000e+02, 3.6000e+02, 8.0000e+01, 8.0000e+00, + 1.0000e+00, 1.0000e+01, 4.5000e+01, 1.2000e+02, 2.1000e+02, 2.5200e+02, + 2.1000e+02, 1.2000e+02, 4.5000e+01, 1.0000e+01, 1.0000e+00 +}; + +std::vector dy_sobel6 { + -1.00000e+00, -1.20000e+01, -6.60000e+01, -2.20000e+02, -4.95000e+02, + -7.92000e+02, -9.24000e+02, -7.92000e+02, -4.95000e+02, -2.20000e+02, + -6.60000e+01, -1.20000e+01, -1.00000e+00, + -1.00000e+01, -1.20000e+02, -6.60000e+02, -2.20000e+03, -4.95000e+03, + -7.92000e+03, -9.24000e+03, -7.92000e+03, -4.95000e+03, -2.20000e+03, + -6.60000e+02, -1.20000e+02, -1.00000e+01, + -4.40000e+01, -5.28000e+02, -2.90400e+03, -9.68000e+03, -2.17800e+04, + -3.48480e+04, -4.06560e+04, -3.48480e+04, -2.17800e+04, -9.68000e+03, + -2.90400e+03, -5.28000e+02, -4.40000e+01, + -1.10000e+02, -1.32000e+03, -7.26000e+03, -2.42000e+04, -5.44500e+04, + -8.71200e+04, -1.01640e+05, -8.71200e+04, -5.44500e+04, -2.42000e+04, + -7.26000e+03, -1.32000e+03, -1.10000e+02, + -1.65000e+02, -1.98000e+03, -1.08900e+04, -3.63000e+04, -8.16750e+04, + -1.30680e+05, -1.52460e+05, -1.30680e+05, -8.16750e+04, -3.63000e+04, + -1.08900e+04, -1.98000e+03, -1.65000e+02, + -1.32000e+02, -1.58400e+03, -8.71200e+03, -2.90400e+04, -6.53400e+04, + -1.04544e+05, -1.21968e+05, -1.04544e+05, -6.53400e+04, -2.90400e+04, + -8.71200e+03, -1.58400e+03, -1.32000e+02, + 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, + 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, + 0.00000e+00, 0.00000e+00, 0.00000e+00, + 1.32000e+02, 1.58400e+03, 8.71200e+03, 2.90400e+04, 6.53400e+04, + 1.04544e+05, 1.21968e+05, 1.04544e+05, 6.53400e+04, 2.90400e+04, + 8.71200e+03, 1.58400e+03, 1.32000e+02, + 1.65000e+02, 1.98000e+03, 1.08900e+04, 3.63000e+04, 8.16750e+04, + 1.30680e+05, 1.52460e+05, 1.30680e+05, 8.16750e+04, 3.63000e+04, + 1.08900e+04, 1.98000e+03, 1.65000e+02, + 1.10000e+02, 1.32000e+03, 7.26000e+03, 2.42000e+04, 5.44500e+04, + 8.71200e+04, 1.01640e+05, 8.71200e+04, 5.44500e+04, 2.42000e+04, + 7.26000e+03, 1.32000e+03, 1.10000e+02, + 4.40000e+01, 5.28000e+02, 2.90400e+03, 9.68000e+03, 2.17800e+04, + 3.48480e+04, 4.06560e+04, 3.48480e+04, 2.17800e+04, 9.68000e+03, + 2.90400e+03, 5.28000e+02, 4.40000e+01, + 1.00000e+01, 1.20000e+02, 6.60000e+02, 2.20000e+03, 4.95000e+03, + 7.92000e+03, 9.24000e+03, 7.92000e+03, 4.95000e+03, 2.20000e+03, + 6.60000e+02, 1.20000e+02, 1.00000e+01, + 1.00000e+00, 1.20000e+01, 6.60000e+01, 2.20000e+02, 4.95000e+02, + 7.92000e+02, 9.24000e+02, 7.92000e+02, 4.95000e+02, 2.20000e+02, + 6.60000e+01, 1.20000e+01, 1.00000e+00 +}; + void test_dx_sobel_kernel() { auto const kernel = gil::generate_dx_sobel(1); BOOST_TEST_ALL_EQ(kernel.begin(), kernel.end(), gil::detail::dx_sobel.begin(), gil::detail::dx_sobel.end()); + + auto const kernel2 = gil::generate_dx_sobel(2); + BOOST_TEST_ALL_EQ(kernel2.begin(), kernel2.end(), dx_sobel2.begin(), dx_sobel2.end()); + + auto const kernel3 = gil::generate_dx_sobel(3); + BOOST_TEST_ALL_EQ(kernel3.begin(), kernel3.end(), dx_sobel3.begin(), dx_sobel3.end()); + + auto const kernel4 = gil::generate_dx_sobel(4); + BOOST_TEST_ALL_EQ(kernel4.begin(), kernel4.end(), dx_sobel4.begin(), dx_sobel4.end()); + + auto const kernel5 = gil::generate_dx_sobel(5); + BOOST_TEST_ALL_EQ(kernel5.begin(), kernel5.end(), dx_sobel5.begin(), dx_sobel5.end()); + + auto const kernel6 = gil::generate_dx_sobel(6); + BOOST_TEST_ALL_EQ(kernel6.begin(), kernel6.end(), dx_sobel6.begin(), dx_sobel6.end()); } void test_dx_scharr_kernel() @@ -32,6 +238,21 @@ void test_dy_sobel_kernel() { auto const kernel = gil::generate_dy_sobel(1); BOOST_TEST_ALL_EQ(kernel.begin(), kernel.end(), gil::detail::dy_sobel.begin(), gil::detail::dy_sobel.end()); + + auto const kernel2 = gil::generate_dy_sobel(2); + BOOST_TEST_ALL_EQ(kernel2.begin(), kernel2.end(), dy_sobel2.begin(), dy_sobel2.end()); + + auto const kernel3 = gil::generate_dy_sobel(3); + BOOST_TEST_ALL_EQ(kernel3.begin(), kernel3.end(), dy_sobel3.begin(), dy_sobel3.end()); + + auto const kernel4 = gil::generate_dy_sobel(4); + BOOST_TEST_ALL_EQ(kernel4.begin(), kernel4.end(), dy_sobel4.begin(), dy_sobel4.end()); + + auto const kernel5 = gil::generate_dy_sobel(5); + BOOST_TEST_ALL_EQ(kernel5.begin(), kernel5.end(), dy_sobel5.begin(), dy_sobel5.end()); + + auto const kernel6 = gil::generate_dy_sobel(6); + BOOST_TEST_ALL_EQ(kernel6.begin(), kernel6.end(), dy_sobel6.begin(), dy_sobel6.end()); } void test_dy_scharr_kernel()