// // Copyright 2019 Miral Shah // Copyright 2019-2021 Pranam Lashkari // // 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 #include #include namespace gil = boost::gil; std::uint8_t img[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; std::uint8_t output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 28, 28, 0, 28, 28, 28, 0, 0, 28, 56, 56, 56, 56, 56, 28, 0, 0, 28, 56, 85, 85, 85, 56, 28, 0, 0, 0, 56, 85, 141, 85, 56, 0, 0, 0, 28, 56, 85, 85, 85, 56, 28, 0, 0, 28, 56, 56, 56, 56, 56, 28, 0, 0, 28, 28, 28, 0, 28, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; void test_convolve_2d_with_normalized_mean_filter() { gil::gray8c_view_t src_view = gil::interleaved_view(9, 9, reinterpret_cast(img), 9); 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); std::vector v(9, 1.0f / 9.0f); gil::detail::kernel_2d kernel(v.begin(), v.size(), 1, 1); gil::detail::convolve_2d(src_view, kernel, dst_view); gil::gray8c_view_t out_view = gil::interleaved_view(9, 9, reinterpret_cast(output), 9); BOOST_TEST(gil::equal_pixels(out_view, dst_view)); } void test_convolve_2d_with_image_using_float32_t() { gil::float32_t img[] = { 0.1, 0.2, 0.1, 0.1, 0.4, 0.1, 0.76, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.4, 0.1, 0.5, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.4, 0.1, 0.5, 0.1, 0.1, 0.1, 0.6, 0.6, 0.1, 0.54, 0.1, 0.5, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.4, 0.1, 0.5, 0.1, 0.1, 0.1, 0.2, 0.1, 0.84, 0.4, 0.1, 0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.4, 0.1, 0.5, 0.1, 0.1, 0.1, 0.3, 0.1, 0.1, 0.4, 0.1, 0.32, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.4, 0.1, 0.21, 0.1, 0.1 }; gil::float32_t exp_output[] = { 0.1, 0.2, 0.1, 0.1, 0.4, 0.1, 0.76, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.4, 0.1, 0.5, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.4, 0.1, 0.5, 0.1, 0.1, 0.1, 0.6, 0.6, 0.1, 0.54, 0.1, 0.5, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.4, 0.1, 0.5, 0.1, 0.1, 0.1, 0.2, 0.1, 0.84, 0.4, 0.1, 0.5, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.4, 0.1, 0.5, 0.1, 0.1, 0.1, 0.3, 0.1, 0.1, 0.4, 0.1, 0.32, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.4, 0.1, 0.21, 0.1, 0.1 }; gil::gray32f_image_t img_gray_out(9, 9); gil::gray32fc_view_t src_view = gil::interleaved_view(9, 9, reinterpret_cast(img), 9); gil::gray32fc_view_t exp_out_view = gil::interleaved_view(9, 9, reinterpret_cast(exp_output), 9); std::vector v(1, 1); gil::detail::kernel_2d kernel(v.begin(), v.size(), 0, 0); // impulse kernel gil::detail::convolve_2d(src_view, kernel, view(img_gray_out)); BOOST_TEST(gil::equal_pixels(exp_out_view, view(img_gray_out))); } void test_convolve_2d_with_sobel_x_filter() { const gil::uint8_t img[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const gil::int16_t exp_output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, -255, -255, 0, 0, 0, 0, 765, 765, 0, 0, -765, -765, 0, 0, 0, 0, 1020, 1020, 0, 0, -1020, -1020, 0, 0, 0, 0, 1020, 1020, 0, 0, -1020, -1020, 0, 0, 0, 0, 1020, 1020, 0, 0, -1020, -1020, 0, 0, 0, 0, 765, 765, 0, 0, -765, -765, 0, 0, 0, 0, 255, 255, 0, 0, -255, -255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; gil::gray16s_image_t img_gray_out(10, 13); const auto src_view = gil::interleaved_view(10, 13, reinterpret_cast(img), 10); const auto exp_out_view = gil::interleaved_view(10, 13, reinterpret_cast(exp_output), 20); gil::detail::convolve_2d(src_view, gil::generate_dx_sobel(1), view(img_gray_out)); BOOST_TEST(gil::equal_pixels(exp_out_view, view(img_gray_out))); } void test_convolve_2d_with_sobel_y_filter() { const gil::uint8_t img[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const gil::int16_t exp_output[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 765, 1020, 1020, 765, 255, 0, 0, 0, 0, 255, 765, 1020, 1020, 765, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, -765, -1020, -1020, -765, -255, 0, 0, 0, 0, -255, -765, -1020, -1020, -765, -255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; gil::gray16s_image_t img_gray_out(10, 13); const auto src_view = gil::interleaved_view(10, 13, reinterpret_cast(img), 10); const auto exp_out_view = gil::interleaved_view(10, 13, reinterpret_cast(exp_output), 20); gil::detail::convolve_2d(src_view, gil::generate_dy_sobel(1), view(img_gray_out)); BOOST_TEST(gil::equal_pixels(exp_out_view, view(img_gray_out))); } int main() { test_convolve_2d_with_normalized_mean_filter(); test_convolve_2d_with_image_using_float32_t(); test_convolve_2d_with_sobel_x_filter(); test_convolve_2d_with_sobel_y_filter(); return ::boost::report_errors(); }