numeric.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //
  2. // Copyright 2013 Krzysztof Czainski
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. #include <boost/gil/image.hpp>
  9. #include <boost/gil/typedefs.hpp>
  10. #include <boost/gil/extension/numeric/resample.hpp>
  11. #include <boost/gil/extension/numeric/sampler.hpp>
  12. #include <boost/assert.hpp>
  13. #define BOOST_TEST_MODULE test_ext_numeric_numeric
  14. #include "unit_test.hpp"
  15. using namespace boost;
  16. using namespace gil;
  17. template < class F, class I >
  18. struct TestMapFn
  19. {
  20. using point_t = point<F>;
  21. using result_type = point_t;
  22. result_type operator()(point<I> const& src) const
  23. {
  24. F x = static_cast<F>( src.x ) - 0.5;
  25. F y = static_cast<F>( src.y ) - 0.5;
  26. return { x, y };
  27. }
  28. };
  29. namespace boost { namespace gil {
  30. // NOTE: I suggest this could be the default behavior:
  31. template <typename T> struct mapping_traits;
  32. template < class F, class I >
  33. struct mapping_traits<TestMapFn<F, I>>
  34. {
  35. using result_type = typename TestMapFn<F, I>::result_type;
  36. };
  37. template <class F, class I>
  38. inline point<F> transform(TestMapFn<F, I> const& mf, point<I> const& src)
  39. {
  40. return mf(src);
  41. }
  42. }} // boost::gil
  43. BOOST_AUTO_TEST_SUITE(Numeric_Tests)
  44. BOOST_AUTO_TEST_CASE( pixel_numeric_operations_plus )
  45. {
  46. rgb8_pixel_t a( 10, 20, 30 );
  47. bgr8_pixel_t b( 30, 20, 10 );
  48. pixel_plus_t< rgb8_pixel_t
  49. , bgr8_pixel_t
  50. , rgb8_pixel_t
  51. > op;
  52. rgb8_pixel_t c = op( a, b );
  53. BOOST_ASSERT( get_color( c, red_t() ) == 20 );
  54. BOOST_ASSERT( get_color( c, green_t() ) == 40 );
  55. BOOST_ASSERT( get_color( c, blue_t() ) == 60 );
  56. pixel_plus_t< rgb8_pixel_t
  57. , bgr8_pixel_t
  58. , bgr8_pixel_t
  59. > op2;
  60. bgr8_pixel_t d = op2( a, b );
  61. BOOST_ASSERT( get_color( d, red_t() ) == 20 );
  62. BOOST_ASSERT( get_color( d, green_t() ) == 40 );
  63. BOOST_ASSERT( get_color( d, blue_t() ) == 60 );
  64. }
  65. BOOST_AUTO_TEST_CASE( pixel_numeric_operations_multiply )
  66. {
  67. rgb32f_pixel_t a( 1.f, 2.f, 3.f );
  68. bgr32f_pixel_t b( 2.f, 2.f, 2.f );
  69. pixel_multiply_t< rgb32f_pixel_t
  70. , bgr32f_pixel_t
  71. , rgb32f_pixel_t
  72. > op;
  73. rgb32f_pixel_t c = op( a, b );
  74. float epsilon = 1e-6f;
  75. BOOST_CHECK_CLOSE( static_cast<float>( get_color( c, red_t() )), 2.f, epsilon );
  76. BOOST_CHECK_CLOSE( static_cast<float>( get_color( c, green_t() )), 4.f, epsilon );
  77. BOOST_CHECK_CLOSE( static_cast<float>( get_color( c, blue_t() )), 6.f, epsilon );
  78. }
  79. BOOST_AUTO_TEST_CASE( pixel_numeric_operations_divide )
  80. {
  81. // integer
  82. {
  83. rgb8_pixel_t a( 10, 20, 30 );
  84. bgr8_pixel_t b( 2, 2, 2 );
  85. pixel_divide_t< rgb8_pixel_t
  86. , bgr8_pixel_t
  87. , rgb8_pixel_t
  88. > op;
  89. rgb32f_pixel_t c = op( a, b );
  90. BOOST_ASSERT( get_color( c, red_t() ) == 5 );
  91. BOOST_ASSERT( get_color( c, green_t() ) == 10 );
  92. BOOST_ASSERT( get_color( c, blue_t() ) == 15 );
  93. }
  94. // float
  95. {
  96. rgb32f_pixel_t a( 1.f, 2.f, 3.f );
  97. bgr32f_pixel_t b( 2.f, 2.f, 2.f );
  98. pixel_divide_t< rgb32f_pixel_t
  99. , bgr32f_pixel_t
  100. , rgb32f_pixel_t
  101. > op;
  102. rgb32f_pixel_t c = op( a, b );
  103. float epsilon = 1e-6f;
  104. BOOST_CHECK_CLOSE( static_cast< float >( get_color( c, red_t() )), 0.5f, epsilon );
  105. BOOST_CHECK_CLOSE( static_cast< float >( get_color( c, green_t() )), 1.f, epsilon );
  106. BOOST_CHECK_CLOSE( static_cast< float >( get_color( c, blue_t() )), 1.5f, epsilon );
  107. }
  108. }
  109. BOOST_AUTO_TEST_CASE(bilinear_sampler_test)
  110. {
  111. // R G B
  112. // G W R
  113. // B R G
  114. rgb8_image_t img(3,3);
  115. rgb8_view_t v = view(img);
  116. v(0,0) = v(1,2) = v(2,1) = rgb8_pixel_t(128,0,0);
  117. v(0,1) = v(1,0) = v(2,2) = rgb8_pixel_t(0,128,0);
  118. v(0,2) = v(2,0) = rgb8_pixel_t(0,0,128);
  119. v(1,1) = rgb8_pixel_t(128,128,128);
  120. rgb8_image_t dimg(4,4);
  121. rgb8c_view_t dv = const_view(dimg);
  122. TestMapFn<double,rgb8_image_t::coord_t> mf;
  123. resample_pixels(const_view(img), view(dimg), mf, bilinear_sampler());
  124. BOOST_ASSERT(rgb8_pixel_t(128,0,0) == dv(0,0));
  125. BOOST_ASSERT(rgb8_pixel_t(64,64,0) == dv(0,1));
  126. BOOST_ASSERT(rgb8_pixel_t(0,64,64) == dv(0,2));
  127. BOOST_ASSERT(rgb8_pixel_t(0,0,128) == dv(0,3));
  128. BOOST_ASSERT(rgb8_pixel_t(64,64,0) == dv(1,0));
  129. BOOST_ASSERT(rgb8_pixel_t(64,96,32) == dv(1,1));
  130. BOOST_ASSERT(rgb8_pixel_t(64,64,64) == dv(1,2));
  131. BOOST_ASSERT(rgb8_pixel_t(64,0,64) == dv(1,3));
  132. BOOST_ASSERT(rgb8_pixel_t(0,64,64) == dv(2,0));
  133. BOOST_ASSERT(rgb8_pixel_t(64,64,64) == dv(2,1));
  134. BOOST_ASSERT(rgb8_pixel_t(96,64,32) == dv(2,2));
  135. BOOST_ASSERT(rgb8_pixel_t(64,64,0) == dv(2,3));
  136. BOOST_ASSERT(rgb8_pixel_t(0,0,128) == dv(3,0));
  137. BOOST_ASSERT(rgb8_pixel_t(64,0,64) == dv(3,1));
  138. BOOST_ASSERT(rgb8_pixel_t(64,64,0) == dv(3,2));
  139. BOOST_ASSERT(rgb8_pixel_t(0,128,0) == dv(3,3));
  140. }
  141. BOOST_AUTO_TEST_SUITE_END()