From d7b82fcb68c7612a6e8cf5a48f1b71ea68097a8f Mon Sep 17 00:00:00 2001 From: Marco Langer Date: Tue, 28 Jun 2022 09:12:15 +0200 Subject: [PATCH] added tests for signed integer and floating point channel types for threshold algorithms --- .../image_processing/threshold_binary.cpp | 72 ++++- .../image_processing/threshold_truncate.cpp | 261 ++++++++++++------ 2 files changed, 251 insertions(+), 82 deletions(-) diff --git a/test/core/image_processing/threshold_binary.cpp b/test/core/image_processing/threshold_binary.cpp index fc39046454..83d0d7f08b 100644 --- a/test/core/image_processing/threshold_binary.cpp +++ b/test/core/image_processing/threshold_binary.cpp @@ -17,12 +17,21 @@ namespace gil = boost::gil; int height = 4; int width = 4; -gil::gray8_image_t original_gray(width, height), threshold_gray(width, height), -expected_gray(width, height); +gil::gray8_image_t original_gray(width, height); +gil::gray8_image_t threshold_gray(width, height); +gil::gray8_image_t expected_gray(width, height); -gil::rgb8_image_t original_rgb(width, height), threshold_rgb(width, height), -expected_rgb(width, height); +gil::rgb8_image_t original_rgb(width, height); +gil::rgb8_image_t threshold_rgb(width, height); +gil::rgb8_image_t expected_rgb(width, height); +gil::rgb8s_image_t original_rgbs(width, height); +gil::rgb8s_image_t threshold_rgbs(width, height); +gil::rgb8s_image_t expected_rgbs(width, height); + +gil::gray32f_image_t original_gray32f(width, height); +gil::gray32f_image_t threshold_gray32f(width, height); +gil::gray32f_image_t expected_gray32f(width, height); void fill_original_gray() { @@ -44,6 +53,26 @@ void fill_original_rgb() original_rgb.width(), original_rgb.height() / 2), gil::rgb8_pixel_t(203, 9, 60)); } +void fill_original_rgbs() +{ + //filling original_rgb view's upper half part with rgbs pixels of value 50, 155, 115 + //filling original_rgb view's lower half part with rgbs pixels of value 203, 9, 60 + gil::fill_pixels(gil::subimage_view(gil::view(original_rgbs), 0, 0, original_rgbs.width(), + original_rgbs.height() / 2), gil::rgb8s_pixel_t(-42, 80, 83)); + gil::fill_pixels(gil::subimage_view(gil::view(original_rgbs), 0, original_rgbs.height() / 2, + original_rgbs.width(), original_rgbs.height() / 2), gil::rgb8s_pixel_t(95, -50, 42)); +} + +void fill_original_gray32f() +{ + //filling original_gray view's upper half part with gray pixels of value 0.3 + //filling original_gray view's lower half part with gray pixels of value 0.7 + gil::fill_pixels(gil::subimage_view(gil::view(original_gray32f), 0, 0, original_gray32f.width(), + original_gray32f.height() / 2), gil::gray32f_pixel_t(0.3f)); + gil::fill_pixels(gil::subimage_view(gil::view(original_gray32f), 0, original_gray32f.height() / 2, + original_gray32f.width(), original_gray32f.height() / 2), gil::gray32f_pixel_t(0.7f)); +} + void binary_gray_to_gray() { //expected_gray view after thresholding of the original_gray view with threshold_gray value of 100 @@ -122,16 +151,51 @@ void binary_inverse_rgb_to_rgb() BOOST_TEST(gil::equal_pixels(gil::view(threshold_rgb), gil::view(expected_rgb))); } +void binary_rgbs_to_rgbs() +{ + //expected_rgbs view after thresholding of the original_rgbs view with threshold value of 70 + //filling expected_rgb view's upper half part with rgb pixels of value -128, 127, 127 + //filling expected_rgb view's lower half part with rgb pixels of value 127, -128, -128 + gil::fill_pixels(gil::subimage_view(gil::view(expected_rgbs), 0, 0, original_rgbs.width(), + original_rgbs.height() / 2), gil::rgb8s_pixel_t(-128, 95, 95)); + gil::fill_pixels(gil::subimage_view(gil::view(expected_rgbs), 0, original_rgbs.height() / 2, + original_rgbs.width(), original_rgbs.height() / 2), gil::rgb8s_pixel_t(95, -128, -128)); + + gil::threshold_binary(gil::view(original_rgbs), gil::view(threshold_rgbs), 70, 95); + + //comparing threshold_rgb view generated by the function with the expected_rgb view + BOOST_TEST(gil::equal_pixels(gil::view(threshold_rgb), gil::view(expected_rgb))); +} + +void binary_gray32f_to_gray32f() +{ + //expected_gray view after thresholding of the original_gray view with threshold_gray value of 0.5f + //filling expected_gray view's upper half part with gray pixels of value 0.0 + //filling expected_gray view's lower half part with gray pixels of value 1.0f + gil::fill_pixels(gil::subimage_view(gil::view(expected_gray32f), 0, 0, original_gray32f.width(), + original_gray32f.height() / 2), gil::gray32f_pixel_t(0.0f)); + gil::fill_pixels(gil::subimage_view(gil::view(expected_gray32f), 0, original_gray32f.height() / 2, + original_gray32f.width(), original_gray32f.height() / 2), gil::gray32f_pixel_t(1.0f)); + + gil::threshold_binary(gil::view(original_gray32f), gil::view(threshold_gray32f), 0.5); + + //comparing threshold_gray view generated by the function with the expected_gray view + BOOST_TEST(gil::equal_pixels(gil::view(threshold_gray32f), gil::view(expected_gray32f))); +} int main() { fill_original_gray(); fill_original_rgb(); + fill_original_rgbs(); + fill_original_gray32f(); binary_gray_to_gray(); binary_inverse_gray_to_gray(); binary_rgb_to_rgb(); + binary_rgbs_to_rgbs(); binary_inverse_rgb_to_rgb(); + binary_gray32f_to_gray32f(); return boost::report_errors(); } diff --git a/test/core/image_processing/threshold_truncate.cpp b/test/core/image_processing/threshold_truncate.cpp index 18266dec67..0c9b15180e 100644 --- a/test/core/image_processing/threshold_truncate.cpp +++ b/test/core/image_processing/threshold_truncate.cpp @@ -14,25 +14,68 @@ namespace gil = boost::gil; +namespace { + int height = 4; int width = 4; -gil::gray8_image_t original_gray(width, height), threshold_gray(width, height), -expected_gray(width, height); +gil::rgb8_image_t original_rgb(width, height); +gil::rgb8_image_t threshold_rgb(width, height); +gil::rgb8_image_t expected_rgb(width, height); + +gil::gray32f_image_t original_gray32f(width, height); +gil::gray32f_image_t threshold_gray32f(width, height); +gil::gray32f_image_t expected_gray32f(width, height); + +gil::rgb8s_image_t original_rgbs(width, height); +gil::rgb8s_image_t threshold_rgbs(width, height); +gil::rgb8s_image_t expected_rgbs(width, height); -gil::rgb8_image_t original_rgb(width, height), threshold_rgb(width, height), -expected_rgb(width, height); +template +void fill_upper_and_lower_half( + View const& view, Pixel const& upper_half_pixel, Pixel const& lower_half_pixel) +{ + fill_pixels( + subimage_view(view, 0, 0, view.width(), view.height() / 2), + upper_half_pixel); + fill_pixels( + subimage_view(view, 0, view.height() / 2, view.width(), view.height() / 2), + lower_half_pixel); +} -void fill_original_gray() +template +void test_threshold( + gil::threshold_truncate_mode mode, + gil::threshold_direction direction, + ChannelValue threshold_value, + Pixel const& upper_half_pixel, + Pixel const& lower_half_pixel, + Pixel const& expected_upper_half_pixel, + Pixel const& expected_lower_half_pixel) { - //filling original view's upper half part with gray pixels of value 50 - //filling original view's lower half part with gray pixels of value 150 - gil::fill_pixels(gil::subimage_view(gil::view(original_gray), 0, 0, original_gray.width(), - original_gray.height() / 2), gil::gray8_pixel_t(50)); - gil::fill_pixels(gil::subimage_view(gil::view(original_gray), 0, original_gray.height() / 2, - original_gray.width(), original_gray.height() / 2), gil::gray8_pixel_t(150)); + int const height = 4; + int const width = 4; + + Image original_img(width, height); + Image threshold_img(width, height); + Image expected_img(width, height); + + auto original_view = gil::view(original_img); + auto threshold_view = gil::view(threshold_img); + auto expected_view = gil::view(expected_img); + + fill_upper_and_lower_half( + original_view, upper_half_pixel, lower_half_pixel); + fill_upper_and_lower_half( + expected_view, expected_upper_half_pixel, expected_lower_half_pixel); + + threshold_truncate(original_view, threshold_view, threshold_value, mode, direction); + + BOOST_TEST(equal_pixels(threshold_view, expected_view)); } +} // namespace + void fill_original_rgb() { //filling original_rgb view's upper half part with rgb pixels of value 50, 85, 135 @@ -43,89 +86,60 @@ void fill_original_rgb() original_rgb.width(), original_rgb.height() / 2), gil::rgb8_pixel_t(150, 205, 106)); } -void threshold_gray_to_gray() +void fill_original_gray32f() { - //expected view after thresholding of the original view with threshold value of 100 - //filling expected view's upper half part with gray pixels of value 50 - //filling expected view's lower half part with gray pixels of value 100 - gil::fill_pixels(gil::subimage_view(gil::view(expected_gray), 0, 0, original_gray.width(), - original_gray.height() / 2), gil::gray8_pixel_t(50)); - gil::fill_pixels(gil::subimage_view(gil::view(expected_gray), 0, original_gray.height() / 2, - original_gray.width(), original_gray.height() / 2), gil::gray8_pixel_t(100)); - - gil::threshold_truncate(gil::view(original_gray), gil::view(threshold_gray), 100); + //filling original view's upper half part with gray pixels of value 0.3 + //filling original view's lower half part with gray pixels of value 0.7 + gil::fill_pixels(gil::subimage_view(gil::view(original_gray32f), 0, 0, original_gray32f.width(), + original_gray32f.height() / 2), gil::gray32f_pixel_t(0.3f)); + gil::fill_pixels(gil::subimage_view(gil::view(original_gray32f), 0, original_gray32f.height() / 2, + original_gray32f.width(), original_gray32f.height() / 2), gil::gray32f_pixel_t(0.7)); +} - //comparing threshold view generated by the function with the expected view - BOOST_TEST(gil::equal_pixels(gil::view(threshold_gray), gil::view(expected_gray))); +void threshold_gray_to_gray() +{ + // truncation mode threshold and direction regular should clip all pixels above the threshold + // to the threshold value + test_threshold( + gil::threshold_truncate_mode::threshold, + gil::threshold_direction::regular, + 100, + gil::gray8_pixel_t{50}, gil::gray8_pixel_t{150}, + gil::gray8_pixel_t{50}, gil::gray8_pixel_t{100}); } void threshold_inverse_gray_to_gray() { - //expected view after thresholding of the original view with threshold value of 100 - //filling expected view's upper half part with gray pixels of value 100 - //filling expected view's lower half part with gray pixels of value 150 - gil::fill_pixels(gil::subimage_view(gil::view(expected_gray), 0, 0, original_gray.width(), - original_gray.height() / 2), gil::gray8_pixel_t(100)); - gil::fill_pixels(gil::subimage_view(gil::view(expected_gray), 0, original_gray.height() / 2, - original_gray.width(), original_gray.height() / 2), gil::gray8_pixel_t(150)); - - gil::threshold_truncate - ( - gil::view(original_gray), - gil::view(threshold_gray), - 100, + // truncation mode threshold and direction inverse should clip all pixels below the threshold + // to the threshold value + test_threshold( gil::threshold_truncate_mode::threshold, - gil::threshold_direction::inverse - ); - - //comparing threshold view generated by the function with the expected view - BOOST_TEST(gil::equal_pixels(gil::view(threshold_gray), gil::view(expected_gray))); + gil::threshold_direction::inverse, + 100, + gil::gray8_pixel_t{50}, gil::gray8_pixel_t{150}, + gil::gray8_pixel_t{100}, gil::gray8_pixel_t{150}); } void zero_gray_to_gray() { - //expected view after thresholding of the original view with threshold value of 100 - //filling expected view's upper half part with gray pixels of value 0 - //filling expected view's lower half part with gray pixels of value 150 - gil::fill_pixels(gil::subimage_view(gil::view(expected_gray), 0, 0, original_gray.width(), - original_gray.height() / 2), gil::gray8_pixel_t(0)); - gil::fill_pixels(gil::subimage_view(gil::view(expected_gray), 0, original_gray.height() / 2, - original_gray.width(), original_gray.height() / 2), gil::gray8_pixel_t(150)); - - gil::threshold_truncate - ( - gil::view(original_gray), - gil::view(threshold_gray), - 100, + // truncation mode zero and direction zero should zero all pixels below the threshold + test_threshold( gil::threshold_truncate_mode::zero, - gil::threshold_direction::regular - ); - - //comparing threshold view generated by the function with the expected view - BOOST_TEST(gil::equal_pixels(gil::view(threshold_gray), gil::view(expected_gray))); + gil::threshold_direction::regular, + 100, + gil::gray8_pixel_t{50}, gil::gray8_pixel_t{150}, + gil::gray8_pixel_t{0}, gil::gray8_pixel_t{150}); } void zero_inverse_gray_to_gray() { - //expected view after thresholding of the original view with threshold value of 100 - //filling expected view's upper half part with gray pixels of value 50 - //filling expected view's lower half part with gray pixels of value 0 - gil::fill_pixels(gil::subimage_view(gil::view(expected_gray), 0, 0, original_gray.width(), - original_gray.height() / 2), gil::gray8_pixel_t(50)); - gil::fill_pixels(gil::subimage_view(gil::view(expected_gray), 0, original_gray.height() / 2, - original_gray.width(), original_gray.height() / 2), gil::gray8_pixel_t(0)); - - gil::threshold_truncate - ( - gil::view(original_gray), - gil::view(threshold_gray), - 100, + // truncation mode zero and direction inverse should zero all pixels above the threshold + test_threshold( gil::threshold_truncate_mode::zero, - gil::threshold_direction::inverse - ); - - //comparing threshold view generated by the function with the expected view - BOOST_TEST(gil::equal_pixels(gil::view(threshold_gray), gil::view(expected_gray))); + gil::threshold_direction::inverse, + 100, + gil::gray8_pixel_t{50}, gil::gray8_pixel_t{150}, + gil::gray8_pixel_t{50}, gil::gray8_pixel_t{0}); } void threshold_rgb_to_rgb() @@ -214,10 +228,96 @@ void zero_inverse_rgb_to_rgb() } +void threshold_gray32f_to_gray32f() +{ + //expected view after thresholding of the original view with threshold value of 0.5f + //filling expected view's upper half part with gray pixels of value 0.3f + //filling expected view's lower half part with gray pixels of value 0.5f + gil::fill_pixels(gil::subimage_view(gil::view(expected_gray32f), 0, 0, original_gray32f.width(), + original_gray32f.height() / 2), gil::gray32f_pixel_t(0.3f)); + gil::fill_pixels(gil::subimage_view(gil::view(expected_gray32f), 0, original_gray32f.height() / 2, + original_gray32f.width(), original_gray32f.height() / 2), gil::gray32f_pixel_t(0.5f)); + + gil::threshold_truncate(gil::view(original_gray32f), gil::view(threshold_gray32f), 0.5f); + + //comparing threshold view generated by the function with the expected view + BOOST_TEST(gil::equal_pixels(gil::view(threshold_gray32f), gil::view(expected_gray32f))); +} + +void threshold_inverse_gray32f_to_gray32f() +{ + //expected view after thresholding of the original view with threshold value of 0.5f + //filling expected view's upper half part with gray pixels of value 0.5f + //filling expected view's lower half part with gray pixels of value 0.7f + gil::fill_pixels(gil::subimage_view(gil::view(expected_gray32f), 0, 0, original_gray32f.width(), + original_gray32f.height() / 2), gil::gray32f_pixel_t(0.5f)); + gil::fill_pixels(gil::subimage_view(gil::view(expected_gray32f), 0, original_gray32f.height() / 2, + original_gray32f.width(), original_gray32f.height() / 2), gil::gray32f_pixel_t(0.7f)); + + gil::threshold_truncate + ( + gil::view(original_gray32f), + gil::view(threshold_gray32f), + 0.5f, + gil::threshold_truncate_mode::threshold, + gil::threshold_direction::inverse + ); + + //comparing threshold view generated by the function with the expected view + BOOST_TEST(gil::equal_pixels(gil::view(threshold_gray32f), gil::view(expected_gray32f))); +} + +void zero_gray32f_to_gray32f() +{ + //expected view after thresholding of the original view with threshold value of 0.5f + //filling expected view's upper half part with gray pixels of value 0.0f + //filling expected view's lower half part with gray pixels of value 0.7f + gil::fill_pixels(gil::subimage_view(gil::view(expected_gray32f), 0, 0, original_gray32f.width(), + original_gray32f.height() / 2), gil::gray32f_pixel_t(0.0f)); + gil::fill_pixels(gil::subimage_view(gil::view(expected_gray32f), 0, original_gray32f.height() / 2, + original_gray32f.width(), original_gray32f.height() / 2), gil::gray32f_pixel_t(0.7f)); + + gil::threshold_truncate + ( + gil::view(original_gray32f), + gil::view(threshold_gray32f), + 0.5f, + gil::threshold_truncate_mode::zero, + gil::threshold_direction::regular + ); + + //comparing threshold view generated by the function with the expected view + BOOST_TEST(gil::equal_pixels(gil::view(threshold_gray32f), gil::view(expected_gray32f))); +} + + +void zero_inverse_gray32f_to_gray32f() +{ + //expected view after thresholding of the original view with threshold value of 0.5f + //filling expected view's upper half part with gray pixels of value 0.3f + //filling expected view's lower half part with gray pixels of value 0.0f + gil::fill_pixels(gil::subimage_view(gil::view(expected_gray32f), 0, 0, original_gray32f.width(), + original_gray32f.height() / 2), gil::gray32f_pixel_t(0.3f)); + gil::fill_pixels(gil::subimage_view(gil::view(expected_gray32f), 0, original_gray32f.height() / 2, + original_gray32f.width(), original_gray32f.height() / 2), gil::gray32f_pixel_t(0.0f)); + + gil::threshold_truncate + ( + gil::view(original_gray32f), + gil::view(threshold_gray32f), + 0.5f, + gil::threshold_truncate_mode::zero, + gil::threshold_direction::inverse + ); + + //comparing threshold view generated by the function with the expected view + BOOST_TEST(gil::equal_pixels(gil::view(threshold_gray32f), gil::view(expected_gray32f))); +} + int main() { - fill_original_gray(); fill_original_rgb(); + fill_original_gray32f(); threshold_gray_to_gray(); threshold_inverse_gray_to_gray(); @@ -229,5 +329,10 @@ int main() zero_rgb_to_rgb(); zero_inverse_rgb_to_rgb(); + threshold_gray32f_to_gray32f(); + threshold_inverse_gray32f_to_gray32f(); + zero_gray32f_to_gray32f(); + zero_inverse_gray32f_to_gray32f(); + return boost::report_errors(); }