resample.hpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. Copyright 2005-2007 Adobe Systems Incorporated
  3. Use, modification and distribution are subject to the Boost Software License,
  4. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. */
  7. /*************************************************************************************************/
  8. #ifndef BOOST_GIL_EXTENSION_NUMERIC_RESAMPLE_HPP
  9. #define BOOST_GIL_EXTENSION_NUMERIC_RESAMPLE_HPP
  10. #include <boost/lambda/lambda.hpp>
  11. #include <boost/lambda/bind.hpp>
  12. #include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
  13. #include <boost/gil/extension/numeric/affine.hpp>
  14. ////////////////////////////////////////////////////////////////////////////////////////
  15. /// \file
  16. /// \brief support for generic image resampling
  17. /// NOTE: The code is for example use only. It is not optimized for performance
  18. /// \author Lubomir Bourdev and Hailin Jin \n
  19. /// Adobe Systems Incorporated
  20. /// \date 2005-2007 \n
  21. ///
  22. ////////////////////////////////////////////////////////////////////////////////////////
  23. namespace boost { namespace gil {
  24. ///////////////////////////////////////////////////////////////////////////
  25. ////
  26. //// resample_pixels: set each pixel in the destination view as the result of a sampling function over the transformed coordinates of the source view
  27. ////
  28. ///////////////////////////////////////////////////////////////////////////
  29. template <typename MapFn> struct mapping_traits {};
  30. /// \brief Set each pixel in the destination view as the result of a sampling function over the transformed coordinates of the source view
  31. /// \ingroup ImageAlgorithms
  32. ///
  33. /// The provided implementation works for 2D image views only
  34. template <typename Sampler, // Models SamplerConcept
  35. typename SrcView, // Models RandomAccess2DImageViewConcept
  36. typename DstView, // Models MutableRandomAccess2DImageViewConcept
  37. typename MapFn> // Models MappingFunctionConcept
  38. void resample_pixels(const SrcView& src_view, const DstView& dst_view, const MapFn& dst_to_src, Sampler sampler=Sampler()) {
  39. typename DstView::point_t dst_dims=dst_view.dimensions();
  40. typename DstView::point_t dst_p;
  41. typename mapping_traits<MapFn>::result_type src_p;
  42. for (dst_p.y=0; dst_p.y<dst_dims.y; ++dst_p.y) {
  43. typename DstView::x_iterator xit = dst_view.row_begin(dst_p.y);
  44. for (dst_p.x=0; dst_p.x<dst_dims.x; ++dst_p.x) {
  45. sample(sampler, src_view, transform(dst_to_src, dst_p), xit[dst_p.x]);
  46. }
  47. }
  48. }
  49. ///////////////////////////////////////////////////////////////////////////
  50. ////
  51. //// resample_pixels when one or both image views are run-time instantiated.
  52. ////
  53. ///////////////////////////////////////////////////////////////////////////
  54. namespace detail {
  55. template <typename Sampler, typename MapFn>
  56. struct resample_pixels_fn : public binary_operation_obj<resample_pixels_fn<Sampler,MapFn> > {
  57. MapFn _dst_to_src;
  58. Sampler _sampler;
  59. resample_pixels_fn(const MapFn& dst_to_src, const Sampler& sampler) : _dst_to_src(dst_to_src), _sampler(sampler) {}
  60. template <typename SrcView, typename DstView> BOOST_FORCEINLINE void apply_compatible(const SrcView& src, const DstView& dst) const {
  61. resample_pixels(src, dst, _dst_to_src, _sampler);
  62. }
  63. };
  64. }
  65. /// \brief resample_pixels when the source is run-time specified
  66. /// If invoked on incompatible views, throws std::bad_cast()
  67. /// \ingroup ImageAlgorithms
  68. template <typename Sampler, typename Types1, typename V2, typename MapFn>
  69. void resample_pixels(const any_image_view<Types1>& src, const V2& dst, const MapFn& dst_to_src, Sampler sampler=Sampler()) {
  70. apply_operation(src,bind(detail::resample_pixels_fn<Sampler,MapFn>(dst_to_src,sampler), _1, dst));
  71. }
  72. /// \brief resample_pixels when the destination is run-time specified
  73. /// If invoked on incompatible views, throws std::bad_cast()
  74. /// \ingroup ImageAlgorithms
  75. template <typename Sampler, typename V1, typename Types2, typename MapFn>
  76. void resample_pixels(const V1& src, const any_image_view<Types2>& dst, const MapFn& dst_to_src, Sampler sampler=Sampler()) {
  77. apply_operation(dst,bind(detail::resample_pixels_fn<Sampler,MapFn>(dst_to_src,sampler), src, _1));
  78. }
  79. /// \brief resample_pixels when both the source and the destination are run-time specified
  80. /// If invoked on incompatible views, throws std::bad_cast()
  81. /// \ingroup ImageAlgorithms
  82. template <typename Sampler, typename SrcTypes, typename DstTypes, typename MapFn>
  83. void resample_pixels(const any_image_view<SrcTypes>& src, const any_image_view<DstTypes>& dst, const MapFn& dst_to_src, Sampler sampler=Sampler()) {
  84. apply_operation(src,dst,detail::resample_pixels_fn<Sampler,MapFn>(dst_to_src,sampler));
  85. }
  86. ///////////////////////////////////////////////////////////////////////////
  87. ////
  88. //// resample_subimage: copy into the destination a rotated rectangular region from the source, rescaling it to fit into the destination
  89. ////
  90. ///////////////////////////////////////////////////////////////////////////
  91. // Extract into dst the rotated bounds [src_min..src_max] rotated at 'angle' from the source view 'src'
  92. // The source coordinates are in the coordinate space of the source image
  93. // Note that the views could also be variants (i.e. any_image_view)
  94. template <typename Sampler, typename SrcMetaView, typename DstMetaView>
  95. void resample_subimage(const SrcMetaView& src, const DstMetaView& dst,
  96. double src_min_x, double src_min_y,
  97. double src_max_x, double src_max_y,
  98. double angle, const Sampler& sampler=Sampler()) {
  99. double src_width = std::max<double>(src_max_x - src_min_x - 1,1);
  100. double src_height = std::max<double>(src_max_y - src_min_y - 1,1);
  101. double dst_width = std::max<double>((double)(dst.width()-1),1);
  102. double dst_height = std::max<double>((double)(dst.height()-1),1);
  103. matrix3x2<double> mat =
  104. matrix3x2<double>::get_translate(-dst_width/2.0, -dst_height/2.0) *
  105. matrix3x2<double>::get_scale(src_width / dst_width, src_height / dst_height)*
  106. matrix3x2<double>::get_rotate(-angle)*
  107. matrix3x2<double>::get_translate(src_min_x + src_width/2.0, src_min_y + src_height/2.0);
  108. resample_pixels(src,dst,mat,sampler);
  109. }
  110. ///////////////////////////////////////////////////////////////////////////
  111. ////
  112. //// resize_view: Copy the source view into the destination, scaling to fit
  113. ////
  114. ///////////////////////////////////////////////////////////////////////////
  115. template <typename Sampler, typename SrcMetaView, typename DstMetaView>
  116. void resize_view(const SrcMetaView& src, const DstMetaView& dst, const Sampler& sampler=Sampler()) {
  117. resample_subimage(src,dst,0.0,0.0,(double)src.width(),(double)src.height(),0.0,sampler);
  118. }
  119. } } // namespace boost::gil
  120. #endif // BOOST_GIL_EXTENSION_NUMERIC_RESAMPLE_HPP