From fc0509add55e1d5220d26e6863229ec80353e123 Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Fri, 6 Mar 2020 05:20:26 +0530 Subject: [PATCH 01/15] Fixed typos in comments --- include/boost/gil/image_processing/threshold.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/gil/image_processing/threshold.hpp b/include/boost/gil/image_processing/threshold.hpp index af05e4d268..96de803772 100644 --- a/include/boost/gil/image_processing/threshold.hpp +++ b/include/boost/gil/image_processing/threshold.hpp @@ -45,7 +45,7 @@ void threshold_impl(SrcView const& src_view, DstView const& dst_view, Operator c typename color_space_type::type >::value, "Source and destination views must have pixels with the same color space"); - //iterate over the image chaecking each pixel value for the threshold + //iterate over the image checking each pixel value for the threshold for (std::ptrdiff_t y = 0; y < src_view.height(); y++) { typename SrcView::x_iterator src_it = src_view.row_begin(y); @@ -64,7 +64,7 @@ void threshold_impl(SrcView const& src_view, DstView const& dst_view, Operator c /// @{ /// /// \brief Direction of image segmentation. -/// The direction specifieds which pixels are considered as corresponding to object +/// The direction specifies which pixels are considered as corresponding to object /// and which pixels correspond to background. enum class threshold_direction { From e569f2bbbbab5228611866614e6a86d076ea79d1 Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sat, 7 Mar 2020 14:42:28 +0530 Subject: [PATCH 02/15] added gaussian filter --- include/boost/gil/image_processing/filter.hpp | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/include/boost/gil/image_processing/filter.hpp b/include/boost/gil/image_processing/filter.hpp index 7b960731a9..1f1590be2a 100644 --- a/include/boost/gil/image_processing/filter.hpp +++ b/include/boost/gil/image_processing/filter.hpp @@ -135,6 +135,64 @@ void median_filter(SrcView const& src_view, DstView const& dst_view, std::size_t } } +namespace detail { + +template +void getGaussianKernel(KernelT& kernel, + long int kernel_size, + double sigma, + bool normalize = true) +{ + if (kernel_size & 0x1) + throw std::invalid_argument("kernel dimensions should be odd"); + + const double exp_denom = 2 * sigma * sigma; + auto center = kernel_size / 2; + for (long int x = 0; x <= center; x++) + { + const auto delta_x = center - x; + const double power = (delta_x * delta_x) / exp_denom; + const double numerator = std::exp(-power); + const float value = static_cast(numerator/(boost::gil::pi * exp_denom)); + kernel[x] = value; + kernel[kernel_size-1-x] = value; + } + if (normalize) + { + auto sum = std::accumulate(kernel.begin(), kernel.end(), 0.0f); + std::for_each(kernel.begin(), kernel.end(), [&sum](float x) { return x/sum; }); + } +} + +} // namespace detail + +template +void gaussian_filter(SrcView src_view, + DstView dst_view, + long int kernel_size, + double sigma, + bool normalize = true, + boundary_option option = boundary_option::extend_zero) +{ + gil_function_requires>(); + gil_function_requires>(); + static_assert(color_spaces_are_compatible + < + typename color_space_type::type, + typename color_space_type::type + >::value, "Source and destination views must have pixels with the same color space"); + + std::vector kernel_values(kernel_size); + detail::getGaussianKernel(kernel_values, kernel_size, sigma, normalize); + auto center = static_cast(kernel_size/2); + kernel_1d kernel(kernel_values.begin(), kernel_size, center); + + detail::convolve_1d + < + pixel + >(src_view, kernel, dst_view, option); +} + }} //namespace boost::gil #endif // !BOOST_GIL_IMAGE_PROCESSING_FILTER_HPP From 49292207d7abb00e45467791fafdef126e61cd9f Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sat, 7 Mar 2020 15:05:07 +0530 Subject: [PATCH 03/15] square root of denominator for 1D Gaussian --- include/boost/gil/image_processing/filter.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/gil/image_processing/filter.hpp b/include/boost/gil/image_processing/filter.hpp index 1f1590be2a..52aaab264c 100644 --- a/include/boost/gil/image_processing/filter.hpp +++ b/include/boost/gil/image_processing/filter.hpp @@ -145,7 +145,7 @@ void getGaussianKernel(KernelT& kernel, { if (kernel_size & 0x1) throw std::invalid_argument("kernel dimensions should be odd"); - + const double exp_denom = 2 * sigma * sigma; auto center = kernel_size / 2; for (long int x = 0; x <= center; x++) @@ -153,7 +153,7 @@ void getGaussianKernel(KernelT& kernel, const auto delta_x = center - x; const double power = (delta_x * delta_x) / exp_denom; const double numerator = std::exp(-power); - const float value = static_cast(numerator/(boost::gil::pi * exp_denom)); + const float value = static_cast(numerator/std::sqrt(boost::gil::pi * exp_denom)); kernel[x] = value; kernel[kernel_size-1-x] = value; } From f739b76c19e1facd005df6c13deafb9311828ea7 Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sat, 7 Mar 2020 16:14:38 +0530 Subject: [PATCH 04/15] kernel size should be odd condition --- include/boost/gil/image_processing/filter.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/gil/image_processing/filter.hpp b/include/boost/gil/image_processing/filter.hpp index 52aaab264c..b98a996a3d 100644 --- a/include/boost/gil/image_processing/filter.hpp +++ b/include/boost/gil/image_processing/filter.hpp @@ -143,7 +143,7 @@ void getGaussianKernel(KernelT& kernel, double sigma, bool normalize = true) { - if (kernel_size & 0x1) + if (!(kernel_size & 0x1)) throw std::invalid_argument("kernel dimensions should be odd"); const double exp_denom = 2 * sigma * sigma; From 73ca6020700a7f3170a6a2e39ae93fa12acbd24d Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sat, 7 Mar 2020 17:00:12 +0530 Subject: [PATCH 05/15] test for Gaussian filter --- .../core/image_processing/gaussian_filter.cpp | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 test/core/image_processing/gaussian_filter.cpp diff --git a/test/core/image_processing/gaussian_filter.cpp b/test/core/image_processing/gaussian_filter.cpp new file mode 100644 index 0000000000..adc4eeadb0 --- /dev/null +++ b/test/core/image_processing/gaussian_filter.cpp @@ -0,0 +1,54 @@ +#define BOOST_TEST_MODULE gil/test/core/image_processing/gaussian_filter +#include "unit_test.hpp" + +#include +#include +#include +#include + +namespace gil = boost::gil; + +const float kernel[] = +{ + 0.241971, 0.398942, 0.241971 +}; + +std::uint8_t img[] = +{ + 0, 0, 0, 0, 0, + 0, 100, 100, 100, 0, + 0, 100, 100, 100, 0, + 0, 100, 100, 100, 0, + 0, 0, 0, 0, 0 +}; + +std::uint8 output[] = +{ + 5, 15, 21, 15, 5, + 15, 41, 56, 41, 15, + 21, 56, 77, 56, 21, + 15, 41, 56, 41, 15, + 5, 15, 21, 15, 5 +}; + +BOOST_AUTO_TEST_SUITE(filter) + +BOOST_AUTO_TEST_CASE(box_filter_with_default_parameters) +{ + gil::gray8c_view_t src_view = + gil::interleaved_view(5, 5, reinterpret_cast(img), 5); + + gil::image temp_img(src_view.width(), src_view.height()); + typename gil::image::view_t temp_view = view(temp_img); + gil::gray8_view_t dst_view(temp_view); + + gil::gaussian_filter(src_view, dst_view, 3, 1.0f); + + gil::gray8c_view_t out_view = + gil::interleaved_view(5, 5, reinterpret_cast(output), 5); + + + BOOST_TEST(gil::equal_pixels(out_view, dst_view)); +} + +BOOST_AUTO_TEST_SUITE_END() From c0a664f9091a957ec902f3b00e980002e2300f69 Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sat, 7 Mar 2020 17:06:08 +0530 Subject: [PATCH 06/15] example for gaussian filter --- example/gaussian_blur.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 example/gaussian_blur.cpp diff --git a/example/gaussian_blur.cpp b/example/gaussian_blur.cpp new file mode 100644 index 0000000000..92bac68721 --- /dev/null +++ b/example/gaussian_blur.cpp @@ -0,0 +1,18 @@ +#include +#include + +using namespace boost::gil; + +int main() +{ + rgb8_image_t img; + read_image("test.jpg",img, jpeg_tag{}); + rgb8_image_t img_out(img.dimensions()); + +// performing binary threshold on each channel of the image +// if the pixel value is more than 150 than it will be set to 255 else to 0 + boost::gil::gaussian_filter(const_view(img), view(img_out), 5, 1.0f); + write_view("gaussian_blur.jpg", view(img_out), jpeg_tag{}); + + return 0; +} From 55665645b2f2f918f3479c045e35a10f136420a7 Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sat, 7 Mar 2020 17:06:38 +0530 Subject: [PATCH 07/15] additional required libraries --- include/boost/gil/image_processing/filter.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/boost/gil/image_processing/filter.hpp b/include/boost/gil/image_processing/filter.hpp index b98a996a3d..b742444898 100644 --- a/include/boost/gil/image_processing/filter.hpp +++ b/include/boost/gil/image_processing/filter.hpp @@ -18,7 +18,9 @@ #include #include - +#include +#include +#include From ab87aa55a697064629013ece2512d34e30495863 Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sat, 7 Mar 2020 17:08:56 +0530 Subject: [PATCH 08/15] appropriate comments --- example/gaussian_blur.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/gaussian_blur.cpp b/example/gaussian_blur.cpp index 92bac68721..e50e84cd74 100644 --- a/example/gaussian_blur.cpp +++ b/example/gaussian_blur.cpp @@ -9,8 +9,8 @@ int main() read_image("test.jpg",img, jpeg_tag{}); rgb8_image_t img_out(img.dimensions()); -// performing binary threshold on each channel of the image -// if the pixel value is more than 150 than it will be set to 255 else to 0 +// performing Gaussian Blur on image +// here kernel size is 5 and sigma is taken as 1 boost::gil::gaussian_filter(const_view(img), view(img_out), 5, 1.0f); write_view("gaussian_blur.jpg", view(img_out), jpeg_tag{}); From 2d2fcf77711e92bbbd02ef42b9d617c983c1a471 Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sat, 7 Mar 2020 18:01:45 +0530 Subject: [PATCH 09/15] gaussian_filter_with_default_parameters --- test/core/image_processing/gaussian_filter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/image_processing/gaussian_filter.cpp b/test/core/image_processing/gaussian_filter.cpp index adc4eeadb0..0b74c891d4 100644 --- a/test/core/image_processing/gaussian_filter.cpp +++ b/test/core/image_processing/gaussian_filter.cpp @@ -33,7 +33,7 @@ std::uint8 output[] = BOOST_AUTO_TEST_SUITE(filter) -BOOST_AUTO_TEST_CASE(box_filter_with_default_parameters) +BOOST_AUTO_TEST_CASE(gaussian_filter_with_default_parameters) { gil::gray8c_view_t src_view = gil::interleaved_view(5, 5, reinterpret_cast(img), 5); From ee5407bcb3b6e660f509ce098790dc8c9ed1f05b Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sat, 7 Mar 2020 19:32:53 +0530 Subject: [PATCH 10/15] boost::gil::pi is replaced with M_PI --- include/boost/gil/image_processing/filter.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/gil/image_processing/filter.hpp b/include/boost/gil/image_processing/filter.hpp index b742444898..6460ce0ad2 100644 --- a/include/boost/gil/image_processing/filter.hpp +++ b/include/boost/gil/image_processing/filter.hpp @@ -155,7 +155,7 @@ void getGaussianKernel(KernelT& kernel, const auto delta_x = center - x; const double power = (delta_x * delta_x) / exp_denom; const double numerator = std::exp(-power); - const float value = static_cast(numerator/std::sqrt(boost::gil::pi * exp_denom)); + const float value = static_cast(numerator/std::sqrt(M_PI * exp_denom)); kernel[x] = value; kernel[kernel_size-1-x] = value; } From 2299630a25812a031436a96871bfe24a98537d23 Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sun, 8 Mar 2020 02:44:38 +0530 Subject: [PATCH 11/15] Gaussian Kernel normalization --- include/boost/gil/image_processing/filter.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/boost/gil/image_processing/filter.hpp b/include/boost/gil/image_processing/filter.hpp index 6460ce0ad2..82930f0247 100644 --- a/include/boost/gil/image_processing/filter.hpp +++ b/include/boost/gil/image_processing/filter.hpp @@ -159,11 +159,6 @@ void getGaussianKernel(KernelT& kernel, kernel[x] = value; kernel[kernel_size-1-x] = value; } - if (normalize) - { - auto sum = std::accumulate(kernel.begin(), kernel.end(), 0.0f); - std::for_each(kernel.begin(), kernel.end(), [&sum](float x) { return x/sum; }); - } } } // namespace detail From a33008e37bbc6d7cc7625ffebb44fe7cef906c4e Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sun, 8 Mar 2020 03:30:16 +0530 Subject: [PATCH 12/15] added Licence and Copyright --- example/gaussian_blur.cpp | 8 ++++++++ test/core/image_processing/gaussian_filter.cpp | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/example/gaussian_blur.cpp b/example/gaussian_blur.cpp index e50e84cd74..bb4bb4a825 100644 --- a/example/gaussian_blur.cpp +++ b/example/gaussian_blur.cpp @@ -1,3 +1,11 @@ +// +// Copyright 2020 Laxmikant Suryavanshi +// +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + #include #include diff --git a/test/core/image_processing/gaussian_filter.cpp b/test/core/image_processing/gaussian_filter.cpp index 0b74c891d4..7e12a7b1ed 100644 --- a/test/core/image_processing/gaussian_filter.cpp +++ b/test/core/image_processing/gaussian_filter.cpp @@ -1,3 +1,11 @@ +// +// Copyright 2020 Laxmikant Suryavanshi +// +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + #define BOOST_TEST_MODULE gil/test/core/image_processing/gaussian_filter #include "unit_test.hpp" From 19ce8b507d665da2f3a26ac45333ae3c64dfbe76 Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sun, 8 Mar 2020 03:33:05 +0530 Subject: [PATCH 13/15] updated to existing coding style of GIL --- include/boost/gil/image_processing/filter.hpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/include/boost/gil/image_processing/filter.hpp b/include/boost/gil/image_processing/filter.hpp index 82930f0247..a7da37e85c 100644 --- a/include/boost/gil/image_processing/filter.hpp +++ b/include/boost/gil/image_processing/filter.hpp @@ -16,11 +16,11 @@ #include #include -#include -#include -#include #include #include +#include +#include +#include @@ -140,12 +140,12 @@ void median_filter(SrcView const& src_view, DstView const& dst_view, std::size_t namespace detail { template -void getGaussianKernel(KernelT& kernel, - long int kernel_size, - double sigma, - bool normalize = true) +void get_gaussian_kernel( + KernelT& kernel, + long int kernel_size, + double sigma) { - if (!(kernel_size & 0x1)) + if (!(kernel_size%2)) throw std::invalid_argument("kernel dimensions should be odd"); const double exp_denom = 2 * sigma * sigma; @@ -164,12 +164,12 @@ void getGaussianKernel(KernelT& kernel, } // namespace detail template -void gaussian_filter(SrcView src_view, - DstView dst_view, - long int kernel_size, - double sigma, - bool normalize = true, - boundary_option option = boundary_option::extend_zero) +void gaussian_filter( + SrcView src_view, + DstView dst_view, + long int kernel_size, + double sigma, + boundary_option option = boundary_option::extend_zero) { gil_function_requires>(); gil_function_requires>(); From 80e88c63b35b8ff8d492eda25dabed97ee3fa1c1 Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sun, 8 Mar 2020 03:36:51 +0530 Subject: [PATCH 14/15] updated kernel size odd condition --- include/boost/gil/image_processing/filter.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/gil/image_processing/filter.hpp b/include/boost/gil/image_processing/filter.hpp index a7da37e85c..8287474b13 100644 --- a/include/boost/gil/image_processing/filter.hpp +++ b/include/boost/gil/image_processing/filter.hpp @@ -145,7 +145,7 @@ void get_gaussian_kernel( long int kernel_size, double sigma) { - if (!(kernel_size%2)) + if ((kernel_size%2) == 0) throw std::invalid_argument("kernel dimensions should be odd"); const double exp_denom = 2 * sigma * sigma; From 53efebba8a8c8e173fe0bfc34152953a911abd4c Mon Sep 17 00:00:00 2001 From: laxsuryavanshi Date: Sun, 8 Mar 2020 15:25:17 +0530 Subject: [PATCH 15/15] get_1d_gaussian_kernel added --- include/boost/gil/image_processing/filter.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/gil/image_processing/filter.hpp b/include/boost/gil/image_processing/filter.hpp index 8287474b13..24c0597a74 100644 --- a/include/boost/gil/image_processing/filter.hpp +++ b/include/boost/gil/image_processing/filter.hpp @@ -140,7 +140,7 @@ void median_filter(SrcView const& src_view, DstView const& dst_view, std::size_t namespace detail { template -void get_gaussian_kernel( +void get_1d_gaussian_kernel( KernelT& kernel, long int kernel_size, double sigma)