simple arithmetic op

sylvain
2007-01-24
2013-04-29
  • sylvain
    sylvain
    2007-01-24

    Hi,

    I would like to know what is the most simplest way to write for example Y = X + t with GIL/boost lambda,
    where X, Y are 2 image views and t is a constant value.

    Thank you

     
    • Lubomir Bourdev
      Lubomir Bourdev
      2007-01-24

      Do you want to perform the same operation for each channel of each pixel of the image?
      Below is an example of how to increment each channel of each pixel without using explicit loop. You should be able to extend it accordingly.

      Lubomir

      struct increment {
          template <typename Incrementable> void operator()(Incrementable& x) const { ++x; }
      };

      struct increment_pixel {
          template <typename Pixel> void operator()(Pixel& x) const {
              for_each_channel(x, increment());
          }
      };

      template <typename View>    // Models MutableImageViewConcept
      void increment_view(const View& view) {
          for_each_pixel(view, increment_pixel());
      }

       
    • sylvain
      sylvain
      2007-01-25

      Do you plan to add a set of basis operation on pixel such like this in GIL ? e.g in pixel_numeric_operations.hpp ?

       
      • Lubomir Bourdev
        Lubomir Bourdev
        2007-01-25

        I think they are useful but I don't think they belong to the GIL core.
        They may be a useful component of the numeric extension, where the image processing algorithms will live.

        Lubomir

         
    • sylvain
      sylvain
      2007-01-25

      Following your advice, here is the code that performs basic arithmetic operations:

      # define self_op(OPNAME, OP)                            \ template <typename C>                                \ struct OPNAME {                                    \   OPNAME(const C& c) : c_(c) {}                            \                                         \   template <typename Self> void operator()(Self& x) const {            \     gil::gil_function_requires<gil::ChannelConvertibleConcept<Self, C> >();    \     x OP##= c_;                                    \   }                                        \                                         \   C c_;                                        \ }                                        \

      self_op(plus_f,+);
      self_op(minus_f,-);
      self_op(times_f,*);
      self_op(div_f,/);
      self_op(and_f,&);
      self_op(or_f,|);
      self_op(xor_f,^);

      # define pixel_self_op(OPNAME)                            \ template <typename C>                                \ struct pixel_##OPNAME {                                \   pixel_##OPNAME(const C& c) : c_(c) {}                        \                                         \   template <typename Pixel> void operator()(Pixel& x) const {            \     gil::for_each_channel(x, OPNAME<C>(c_));                    \   }                                        \                                         \   C c_;                                        \ }                                        \

      pixel_self_op(plus_f);
      pixel_self_op(minus_f);
      pixel_self_op(times_f);
      pixel_self_op(div_f);
      pixel_self_op(and_f);
      pixel_self_op(or_f);
      pixel_self_op(xor_f);

      example:

      bits8 v = 100;

      for_each_pixel(view(src), pixel_plus_f<bits8>(v));

      A thing like that could be part of pixel_numeric_operations.hpp

      Regards

       
    • Hirotaka NIITSUMA
      Hirotaka NIITSUMA
      2007-01-25

      How about, describe these operations in
      boost/numeric/functional/gil.hpp

       
    • Hirotaka NIITSUMA
      Hirotaka NIITSUMA
      2007-01-25

      I am appreciate, if sig template is added to the above code for lambda.

      # define self_op(OPNAME, OP) \
      template <typename C> \
      struct OPNAME { \
      typedef void result_type;\ template <class Args> struct sig { typedef void type; }; \ OPNAME(const C& c) : c_(c) {} \
      \
      template <typename Self> void operator()(Self& x) const { \
      gil::gil_function_requires<gil::ChannelConvertibleConcept<Self, C> >(); \
      x OP##= c_; \
      } \
      \
      C c_; \
      } \

      self_op(plus_f,+);
      self_op(minus_f,-);
      self_op(times_f,*);
      self_op(div_f,/);
      self_op(and_f,&);
      self_op(or_f,|);
      self_op(xor_f,^);

      # undef self_op

      # define pixel_self_op(OPNAME) \
      template <typename C> \
      struct pixel_##OPNAME { \
      template <class Args> struct sig { \     typedef typename boost::remove_const<\         typename boost::tuples::element<1, Args>::type \      >::type type; \ };\ pixel_##OPNAME(const C& c) : c_(c) {} \
      \
      template <typename Pixel> void operator()(Pixel& x) const { \
      gil::for_each_channel(x, OPNAME<C>(c_)); \
      } \
      \
      C c_; \
      } \

      pixel_self_op(plus_f);
      pixel_self_op(minus_f);
      pixel_self_op(times_f);
      pixel_self_op(div_f);
      pixel_self_op(and_f);
      pixel_self_op(or_f);
      pixel_self_op(xor_f);

      #undef pixel_self_op

       
    • sylvain
      sylvain
      2007-01-25

      I agree.

      Sylvain