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