-
Notifications
You must be signed in to change notification settings - Fork 170
Expand file tree
/
Copy pathconvolve_rows.cpp
More file actions
126 lines (108 loc) · 4.94 KB
/
convolve_rows.cpp
File metadata and controls
126 lines (108 loc) · 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//
// Copyright 2019-2020 Mateusz Loskot <mateusz at loskot dot net>
// Copyright 2021 Pranam Lashkari <plashkari628@gmail.com>
// Copyright 2021 Prathamesh Tagore <prathameshtagore@gmail.com>
//
// Distributed under 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 <boost/gil.hpp>
#include <boost/gil/image_processing/convolve.hpp>
#include <boost/core/lightweight_test.hpp>
#include <tuple>
#include <type_traits>
#include "test_fixture.hpp"
#include "core/image/test_fixture.hpp"
namespace gil = boost::gil;
namespace fixture = boost::gil::test::fixture;
struct test_image_1x1_kernel_1x1_identity
{
template <typename Image>
void operator()(Image const&)
{
using image_t = Image;
auto const img = fixture::create_image<image_t>(1, 1, 7);
auto img_out = fixture::create_image<image_t>(1, 1, 0);
using pixel_t = typename image_t::value_type;
using channel_t = typename gil::channel_type<pixel_t>::type;
auto const kernel = fixture::create_kernel<channel_t>({1});
gil::convolve_rows<pixel_t>(const_view(img), kernel, view(img_out));
// 1x1 kernel reduces convolution to multiplication
BOOST_TEST(gil::const_view(img).front() == gil::const_view(img_out).front());
}
static void run()
{
boost::mp11::mp_for_each<fixture::image_types>(test_image_1x1_kernel_1x1_identity{});
}
};
struct test_image_1x1_kernel_3x3_identity
{
template <typename Image>
void operator()(Image const&)
{
using image_t = Image;
auto const img = fixture::create_image<image_t>(1, 1, 7);
auto img_out = fixture::create_image<image_t>(1, 1, 0);
using pixel_t = typename image_t::value_type;
using channel_t = typename gil::channel_type<pixel_t>::type;
auto const kernel = fixture::create_kernel<channel_t>({0, 0, 0, 0, 1, 0, 0, 0, 0});
gil::convolve_rows<pixel_t>(const_view(img), kernel, view(img_out));
BOOST_TEST(gil::const_view(img).front() == gil::const_view(img_out).front());
}
static void run()
{
boost::mp11::mp_for_each<fixture::image_types>(test_image_1x1_kernel_3x3_identity{});
}
};
struct test_image_5x5_kernel_1x9_boundary_extend_reflection
{
template <typename Image>
void operator()(Image const&)
{
using image_t = Image;
using pixel_t = typename image_t::value_type;
using channel_t = typename gil::channel_type<pixel_t>::type;
auto img = fixture::generate_image<image_t>(5, 5, fixture::random_value<channel_t>{});
auto img_view = gil::view(img);
image_t img_out_up_offset(img), img_expected_up_offset(img);
image_t img_out_down_offset(img), img_expected_down_offset(img);
int kernel_shift_up_offset = 2, kernel_shift_down_offset = -2;
fixture::row_conv1D_offset_img_generator(img_view, gil::view(img_expected_up_offset),
kernel_shift_up_offset);
fixture::row_conv1D_offset_img_generator(img_view, gil::view(img_expected_up_offset),
-1, 0, 1, img_view.height(), 1);
fixture::row_conv1D_offset_img_generator(img_view, gil::view(img_expected_up_offset),
1, 0, 0, img_view.height(), 2);
fixture::row_conv1D_offset_img_generator(img_view, gil::view(img_expected_down_offset),
kernel_shift_down_offset, 0, 2, img_view.height(), img_view.width());
fixture::row_conv1D_offset_img_generator(img_view, gil::view(img_expected_down_offset),
-1, 0, img_view.width() - 1, img_view.height(), img_view.width());
fixture::row_conv1D_offset_img_generator(img_view, gil::view(img_expected_down_offset),
1, 0, img_view.width() - 2, img_view.height(), img_view.width());
auto const kernel_up_offset = fixture::create_kernel<channel_t>(
{0, 0, 0, 0, 0, 0, 1, 0, 0});
gil::convolve_rows<pixel_t>(gil::const_view(img), kernel_up_offset,
gil::view(img_out_up_offset), gil::boundary_option::extend_reflection);
auto const kernel_down_offset = fixture::create_kernel<channel_t>(
{0, 0, 1, 0, 0, 0, 0, 0, 0});
gil::convolve_rows<pixel_t>(gil::const_view(img), kernel_down_offset,
gil::view(img_out_down_offset), gil::boundary_option::extend_reflection);
BOOST_TEST(gil::equal_pixels(gil::const_view(img_out_up_offset),
gil::const_view(img_expected_up_offset)));
BOOST_TEST(gil::equal_pixels(gil::const_view(img_out_down_offset),
gil::const_view(img_expected_down_offset)));
}
static void run()
{
boost::mp11::mp_for_each<fixture::image_types>(
test_image_5x5_kernel_1x9_boundary_extend_reflection{});
}
};
int main()
{
test_image_1x1_kernel_1x1_identity::run();
test_image_1x1_kernel_3x3_identity::run();
test_image_5x5_kernel_1x9_boundary_extend_reflection::run();
return ::boost::report_errors();
}