1 //
2 // Copyright 2019-2020 Mateusz Loskot <mateusz at loskot dot net>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 #include <boost/gil.hpp>
9 #include <boost/gil/extension/numeric/convolve.hpp>
10
11 #include <boost/core/lightweight_test.hpp>
12
13 #include <tuple>
14 #include <type_traits>
15
16 #include "test_fixture.hpp"
17 #include "core/test_fixture.hpp"
18 #include "core/image/test_fixture.hpp"
19
20 namespace gil = boost::gil;
21 namespace fixture = boost::gil::test::fixture;
22
23 struct test_image_1x1_kernel_1x1_identity
24 {
25 template <typename Image>
operator ()test_image_1x1_kernel_1x1_identity26 void operator()(Image const&)
27 {
28 using image_t = Image;
29 auto const img = fixture::create_image<image_t>(1, 1, 7);
30 image_t img_out(img);
31
32 using pixel_t = typename image_t::value_type;
33 using channel_t = typename gil::channel_type<pixel_t>::type;
34 auto const kernel = fixture::create_kernel<channel_t>({1});
35 gil::detail::convolve_1d<pixel_t>(gil::const_view(img_out), kernel, gil::view(img_out));
36
37 // 1x1 kernel reduces convolution to multiplication
38 BOOST_TEST(gil::const_view(img).front() == gil::const_view(img_out).front());
39 }
runtest_image_1x1_kernel_1x1_identity40 static void run()
41 {
42 boost::mp11::mp_for_each<fixture::image_types>(test_image_1x1_kernel_1x1_identity{});
43 }
44 };
45
46 struct test_image_1x1_kernel_3x3_identity
47 {
48 template <typename Image>
operator ()test_image_1x1_kernel_3x3_identity49 void operator()(Image const&)
50 {
51 using image_t = Image;
52 auto const img = fixture::create_image<Image>(1, 1, 7);
53 image_t img_out(img);
54
55 using pixel_t = typename image_t::value_type;
56 using channel_t = typename gil::channel_type<pixel_t>::type;
57 auto const kernel = fixture::create_kernel<channel_t>({0, 0, 0, 0, 1, 0, 0, 0, 0});
58 gil::detail::convolve_1d<pixel_t>(gil::const_view(img_out), kernel, gil::view(img_out));
59
60 BOOST_TEST(gil::const_view(img).front() == gil::const_view(img_out).front());
61 }
runtest_image_1x1_kernel_3x3_identity62 static void run()
63 {
64 boost::mp11::mp_for_each<fixture::image_types>(test_image_1x1_kernel_3x3_identity{});
65 }
66 };
67
68 struct test_image_3x3_kernel_3x3_identity
69 {
70 template <typename Image>
operator ()test_image_3x3_kernel_3x3_identity71 void operator()(Image const&)
72 {
73 using image_t = Image;
74 using pixel_t = typename image_t::value_type;
75 using channel_t = typename gil::channel_type<pixel_t>::type;
76 auto const img = fixture::generate_image<image_t>(3, 3, fixture::random_value<channel_t>{});
77 image_t img_out(img);
78
79 auto const kernel = fixture::create_kernel<channel_t>({0, 0, 0, 0, 1, 0, 0, 0, 0});
80 gil::detail::convolve_1d<pixel_t>(gil::const_view(img_out), kernel, gil::view(img_out));
81
82 BOOST_TEST(gil::equal_pixels(gil::const_view(img), gil::const_view(img_out)));
83 }
runtest_image_3x3_kernel_3x3_identity84 static void run()
85 {
86 boost::mp11::mp_for_each<fixture::image_types>(test_image_3x3_kernel_3x3_identity{});
87 }
88 };
89
90 struct test_image_5x5_kernel_3x3_identity
91 {
92 template <typename Image>
operator ()test_image_5x5_kernel_3x3_identity93 void operator()(Image const&)
94 {
95 using image_t = Image;
96 using pixel_t = typename image_t::value_type;
97 using channel_t = typename gil::channel_type<pixel_t>::type;
98 auto const img = fixture::generate_image<image_t>(5, 5, fixture::random_value<channel_t>{});
99 image_t img_out(img);
100
101 auto const kernel = fixture::create_kernel<channel_t>({0, 0, 0, 0, 1, 0, 0, 0, 0});
102 gil::detail::convolve_1d<pixel_t>(gil::const_view(img_out), kernel, gil::view(img_out));
103 // TODO: Test different boundary options
104
105 BOOST_TEST(gil::equal_pixels(gil::const_view(img), gil::const_view(img_out)));
106 }
runtest_image_5x5_kernel_3x3_identity107 static void run()
108 {
109 boost::mp11::mp_for_each<fixture::image_types>(test_image_5x5_kernel_3x3_identity{});
110 }
111 };
112
main()113 int main()
114 {
115 test_image_1x1_kernel_1x1_identity::run();
116 test_image_1x1_kernel_3x3_identity::run();
117 test_image_3x3_kernel_3x3_identity::run();
118 test_image_5x5_kernel_3x3_identity::run();
119
120 return ::boost::report_errors();
121 }
122