1
1
//
2
2
// Copyright 2019-2020 Mateusz Loskot <mateusz at loskot dot net>
3
3
// Copyright 2021 Pranam Lashkari <[email protected] >
4
+ // Copyright 2021 Prathamesh Tagore <[email protected] >
4
5
//
5
6
// Distributed under the Boost Software License, Version 1.0
6
7
// See accompanying file LICENSE_1_0.txt or copy at
@@ -101,7 +102,6 @@ struct test_image_5x5_kernel_3x3_identity
101
102
102
103
auto const kernel = fixture::create_kernel<channel_t >({0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 });
103
104
gil::detail::convolve_1d<pixel_t >(gil::const_view (img_out), kernel, gil::view (img_out));
104
- // TODO: Test different boundary options
105
105
106
106
BOOST_TEST (gil::equal_pixels (gil::const_view (img), gil::const_view (img_out)));
107
107
}
@@ -111,12 +111,210 @@ struct test_image_5x5_kernel_3x3_identity
111
111
}
112
112
};
113
113
114
+ // Convention used for naming variables :
115
+ // 1. img : Original image which is to be used for testing.
116
+ // 2. img_out : Output image obtained after applying 1D row and column convolution using library
117
+ // function.
118
+ // 3. img_expected_row : Expected image after applying row convolution on "img".
119
+ // 4. img_expected_col : Expected image after applying column convolution on "img_expected_row".
120
+
121
+ struct test_image_5x5_kernel_1x9_boundary_extend_zero
122
+ {
123
+ template <typename Image>
124
+ void operator ()(Image const &)
125
+ {
126
+ using image_t = Image;
127
+ using pixel_t = typename image_t ::value_type;
128
+ using channel_t = typename gil::channel_type<pixel_t >::type;
129
+ auto img = fixture::generate_image<image_t >(5 , 5 , fixture::random_value<channel_t >{});
130
+ auto img_view = gil::view (img);
131
+ image_t img_out (img), img_expected_row (img_view.width (), img_view.height ());
132
+ image_t img_expected_col (img_view.width (), img_view.height ());
133
+ unsigned int const kernel_shift_offset = 2 ;
134
+
135
+ fixture::row_conv1D_offset_img_generator (img_view, gil::view (img_expected_row),
136
+ kernel_shift_offset);
137
+ fixture::col_conv1D_offset_img_generator (gil::view (img_expected_row),
138
+ gil::view (img_expected_col), kernel_shift_offset);
139
+
140
+ auto const kernel_shift_by_two = fixture::create_kernel<channel_t >(
141
+ {0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 });
142
+ gil::detail::convolve_1d<pixel_t >(gil::const_view (img), kernel_shift_by_two,
143
+ gil::view (img_out), boost::gil::boundary_option::extend_zero);
144
+
145
+ BOOST_TEST (gil::equal_pixels (gil::const_view (img_out), gil::const_view (img_expected_col)));
146
+ }
147
+ static void run ()
148
+ {
149
+ boost::mp11::mp_for_each<fixture::image_types>(
150
+ test_image_5x5_kernel_1x9_boundary_extend_zero{});
151
+ }
152
+ };
153
+
154
+ struct test_image_5x5_kernel_1x9_boundary_extend_constant
155
+ {
156
+ template <typename Image>
157
+ void operator ()(Image const &)
158
+ {
159
+ using image_t = Image;
160
+ using pixel_t = typename image_t ::value_type;
161
+ using channel_t = typename gil::channel_type<pixel_t >::type;
162
+ auto img = fixture::generate_image<image_t >(5 , 5 , fixture::random_value<channel_t >{});
163
+ auto img_view = gil::view (img);
164
+ image_t img_out (img), img_expected_row (img);
165
+ unsigned int const kernel_shift_offset = 2 ;
166
+
167
+ fixture::row_conv1D_offset_img_generator (img_view, gil::view (img_expected_row),
168
+ kernel_shift_offset);
169
+ fixture::row_conv1D_offset_img_generator (img_view, gil::view (img_expected_row),
170
+ 1 , 0 , 0 , img_view.height (), 2 );
171
+
172
+ image_t img_expected_col (img_expected_row);
173
+
174
+ fixture::col_conv1D_offset_img_generator (gil::view (img_expected_row),
175
+ gil::view (img_expected_col), kernel_shift_offset);
176
+ fixture::col_conv1D_offset_img_generator (gil::view (img_expected_row),
177
+ gil::view (img_expected_col), 1 , 0 , 0 , 2 , img_view.width ());
178
+
179
+ auto const kernel_shift_by_two = fixture::create_kernel<channel_t >({0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 });
180
+ gil::detail::convolve_1d<pixel_t >(gil::const_view (img), kernel_shift_by_two,
181
+ gil::view (img_out), boost::gil::boundary_option::extend_constant);
182
+
183
+ BOOST_TEST (gil::equal_pixels (gil::const_view (img_out), gil::const_view (img_expected_col)));
184
+ }
185
+ static void run ()
186
+ {
187
+ boost::mp11::mp_for_each<fixture::image_types>(
188
+ test_image_5x5_kernel_1x9_boundary_extend_constant{});
189
+ }
190
+ };
191
+
192
+ struct test_image_5x5_kernel_1x3_boundary_output_zero
193
+ {
194
+ template <typename Image>
195
+ void operator ()(Image const &)
196
+ {
197
+ using image_t = Image;
198
+ using pixel_t = typename image_t ::value_type;
199
+ using channel_t = typename gil::channel_type<pixel_t >::type;
200
+ auto img = fixture::generate_image<image_t >(5 , 5 , fixture::random_value<channel_t >{});
201
+ auto img_view = gil::view (img);
202
+ image_t img_out (img), img_expected_row (img_view.width (), img_view.height ());
203
+ image_t img_expected_col (img_view.width (), img_view.height ());
204
+ unsigned int const kernel_shift_offset = 1 ;
205
+
206
+ fixture::row_conv1D_offset_img_generator (img_view, gil::view (img_expected_row),
207
+ kernel_shift_offset, 0 , 0 , img_view.height (), img_view.width () - 1 );
208
+ fixture::col_conv1D_offset_img_generator (gil::view (img_expected_row),
209
+ gil::view (img_expected_col), kernel_shift_offset, 0 , 0 , img_view.height () - 1 ,
210
+ img_view.width ());
211
+
212
+ auto const kernel_shift_by_one = fixture::create_kernel<channel_t >({0 , 0 , 1 });
213
+ gil::detail::convolve_1d<pixel_t >(gil::const_view (img), kernel_shift_by_one,
214
+ gil::view (img_out), boost::gil::boundary_option::output_zero);
215
+
216
+ BOOST_TEST (gil::equal_pixels (gil::const_view (img_out), gil::const_view (img_expected_col)));
217
+ }
218
+ static void run ()
219
+ {
220
+ boost::mp11::mp_for_each<fixture::image_types>(
221
+ test_image_5x5_kernel_1x3_boundary_output_zero{});
222
+ }
223
+ };
224
+
225
+ struct test_image_5x5_kernel_1x3_boundary_output_ignore
226
+ {
227
+ template <typename Image>
228
+ void operator ()(Image const &)
229
+ {
230
+ using image_t = Image;
231
+ using pixel_t = typename image_t ::value_type;
232
+ using channel_t = typename gil::channel_type<pixel_t >::type;
233
+ auto img = fixture::generate_image<image_t >(5 , 5 , fixture::random_value<channel_t >{});
234
+ auto img_view = gil::view (img);
235
+ image_t img_out (img), img_expected_row (img);
236
+ unsigned int const kernel_shift_offset = 1 ;
237
+
238
+ fixture::row_conv1D_offset_img_generator (img_view, gil::view (img_expected_row),
239
+ kernel_shift_offset, 0 , 0 , img_view.height (), img_view.width () - 1 );
240
+
241
+ image_t img_expected_col (img_expected_row);
242
+
243
+ fixture::col_conv1D_offset_img_generator (gil::view (img_expected_row),
244
+ gil::view (img_expected_col), kernel_shift_offset, 0 , 0 , img_view.height () - 1 ,
245
+ img_view.width ());
246
+
247
+ auto const kernel_shift_by_one = fixture::create_kernel<channel_t >({0 , 0 , 1 });
248
+ gil::detail::convolve_1d<pixel_t >(gil::const_view (img), kernel_shift_by_one,
249
+ gil::view (img_out), gil::boundary_option::output_ignore);
250
+
251
+ BOOST_TEST (gil::equal_pixels (gil::const_view (img_out), gil::const_view (img_expected_col)));
252
+ }
253
+ static void run ()
254
+ {
255
+ boost::mp11::mp_for_each<fixture::image_types>(
256
+ test_image_5x5_kernel_1x3_boundary_output_ignore{});
257
+ }
258
+ };
259
+
260
+ struct test_image_5x5_kernel_1x3_boundary_extend_padded
261
+ {
262
+ template <typename Image>
263
+ void operator ()(Image const &)
264
+ {
265
+ using image_t = Image;
266
+ using pixel_t = typename image_t ::value_type;
267
+ using channel_t = typename gil::channel_type<pixel_t >::type;
268
+ auto img = fixture::generate_image<image_t >(5 , 5 , fixture::random_value<channel_t >{});
269
+ auto img_view = gil::view (img);
270
+ image_t img_out (img), img_expected_row (img);
271
+ unsigned int const kernel_shift_offset = 1 ;
272
+
273
+ fixture::row_conv1D_offset_img_generator (img_view, gil::view (img_expected_row),
274
+ kernel_shift_offset);
275
+
276
+ image_t img_expected_col (img_expected_row);
277
+
278
+ fixture::col_conv1D_offset_img_generator (gil::view (img_expected_row),
279
+ gil::view (img_expected_col), kernel_shift_offset);
280
+
281
+ auto const kernel_shift_by_one = fixture::create_kernel<channel_t >({0 , 0 , 1 });
282
+ gil::detail::convolve_1d<pixel_t >(gil::const_view (img), kernel_shift_by_one,
283
+ gil::view (img_out), gil::boundary_option::extend_padded);
284
+
285
+ // First row and first column of "img_out" and "img_expected_col" are intentionally made
286
+ // similar.
287
+ auto img_out_it1 = gil::view (img_out).col_begin (0 );
288
+ auto img_expected_col_it1 = gil::view (img_expected_col).col_begin (0 );
289
+ for (std::ptrdiff_t x = 0 ; x < gil::view (img_out).width (); ++x)
290
+ img_expected_col_it1[x] = img_out_it1[x];
291
+
292
+ auto img_out_it2 = gil::view (img_out).row_begin (0 );
293
+ auto img_expected_col_it2 = gil::view (img_expected_col).row_begin (0 );
294
+ for (std::ptrdiff_t y = 0 ; y < gil::view (img_out).height (); ++y)
295
+ img_expected_col_it2[y] = img_out_it2[y];
296
+
297
+ BOOST_TEST (gil::equal_pixels (gil::const_view (img_out), gil::const_view (img_expected_col)));
298
+
299
+ }
300
+ static void run ()
301
+ {
302
+ boost::mp11::mp_for_each<fixture::image_types>(
303
+ test_image_5x5_kernel_1x3_boundary_extend_padded{});
304
+ }
305
+ };
306
+
114
307
int main ()
115
308
{
116
309
test_image_1x1_kernel_1x1_identity::run ();
117
310
test_image_1x1_kernel_3x3_identity::run ();
118
311
test_image_3x3_kernel_3x3_identity::run ();
119
312
test_image_5x5_kernel_3x3_identity::run ();
120
313
314
+ test_image_5x5_kernel_1x9_boundary_extend_zero::run ();
315
+ test_image_5x5_kernel_1x9_boundary_extend_constant::run ();
316
+ test_image_5x5_kernel_1x3_boundary_output_zero::run ();
317
+ test_image_5x5_kernel_1x3_boundary_output_ignore::run ();
318
+ test_image_5x5_kernel_1x3_boundary_extend_padded::run ();
121
319
return ::boost::report_errors ();
122
320
}
0 commit comments