[GIL] any_image difference
Hi all, What is the best way to compute the difference between 2 any_image? Of course, the input any_image may not be of the same type... So, if pixels are unsigned int for the 1st one and double for the 2nd one, the result must be stored as double. I (accidently) found pixel_minus_t in pixel_numeric_operations.hpp but cannot figure how to use it. Hope you could help. Regards, Olivier
Hi, 2010/11/5 Olivier Tournaire <olitour@gmail.com>
Hi all,
What is the best way to compute the difference between 2 any_image? Of course, the input any_image may not be of the same type... So, if pixels are unsigned int for the 1st one and double for the 2nd one, the result must be stored as double. I (accidently) found pixel_minus_t in pixel_numeric_operations.hpp but cannot figure how to use it.
I am still having problem with this. I found a way to write such an image difference, but not for any_image. Here is what I have now: namespace boost { namespace gil { typedef double bits64F; GIL_DEFINE_BASE_TYPEDEFS(64F,gray) typedef float bits32F; GIL_DEFINE_BASE_TYPEDEFS(32F,gray) } } struct image_difference { typedef void result_type; template<typename OutputViewType, typename ViewType1, typename ViewType2> result_type operator()(OutputViewType &out, const ViewType1 &v1, const ViewType2 &v2) const { typedef typename get_pixel_type<ViewType1>::type v1_pixel_t; typedef typename get_pixel_type<ViewType2>::type v2_pixel_t; typedef typename get_pixel_type<OutputViewType>::type out_pixel_t; typename ViewType1::iterator v1_it = v1.begin(); typename ViewType2::iterator v2_it = v2.begin(); typename OutputViewType::iterator out_it = out.begin(); for(;v1_it!=v1.end();++v1_it, ++v2_it, ++out_it) *out_it = pixel_minus_t<v1_pixel_t, v2_pixel_t, out_pixel_t>()(*v1_it, *v2_it); } }; int main(int argc, char** argv) { gray16s_image_t mns; gray32F_image_t mnt, mne; read_image( "/home/olivier/work/data/ZTerrain_c3/ZTerrain_c3.tif", mns , tiff_tag() ); read_image( "/home/olivier/work/data/ZTerrain_c3/ZTerrain_c3_MNT.tif", mnt , tiff_tag() ); mne.recreate( mns.width(), mns.height() ); image_difference()( view(mne) , view(mns) , view(mnt) ); write_view( "/home/olivier/work/data/ZTerrain_c3/ZTerrain_c3_MNE.tif", view(mne), tiff_tag() ); } I am however sure there is a generic and better way to do such a simple image operation. 2 questions arise: 1) how can I use for_each_pixel in image_difference rather than a for loop? 2) how can I extend this code to work on any_image(_view) using apply_operation? Best regards, Olivier
Hi Olivier, sorry for the late reply. Interesting problem you have and I started looking into it.
What is the best way to compute the difference between 2 any_image? Of course, the input any_image may not be of the same type... So, if pixels are unsigned int for the 1st one and double for the 2nd one, the result must be stored as double. I (accidently) found pixel_minus_t in pixel_numeric_operations.hpp but cannot figure how to use it.
Where did you find pixel_numeric_operations.hpp? Regards, Christian
Hi Christian, 2010/11/6 Christian Henning <chhenning@gmail.com>
Hi Olivier, sorry for the late reply. Interesting problem you have and I started looking into it.
Great, thank you! What about my first solution?
What is the best way to compute the difference between 2 any_image? Of course, the input any_image may not be of the same type... So, if pixels are unsigned int for the 1st one and double for the 2nd one, the result must be stored as double. I (accidently) found pixel_minus_t in pixel_numeric_operations.hpp but cannot figure how to use it.
Where did you find pixel_numeric_operations.hpp?
in extension/numeric Regards, Olivier
Regards, Christian _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi Olivier,
Great, thank you! What about my first solution?
Yes. I think it's the right way. Here is what I have which uses transform_pixels. #include <boost\gil\gil_all.hpp> #include <boost\gil\extension\numeric\pixel_numeric_operations.hpp> namespace boost { namespace gil { typedef double bits64F; GIL_DEFINE_BASE_TYPEDEFS(64F,gray) typedef float bits32F; GIL_DEFINE_BASE_TYPEDEFS(32F,gray) } } using namespace boost; using namespace gil; template< typename DST, typename SRC1, typename SRC2 > DST generate_diff( const SRC1& src1, const SRC2& src2 ) { return pixel_minus_t<SRC1, SRC2, DST>()(src1, src1); } int main(int argc, char** argv) { gray16s_image_t mns( 10, 10 ); gray32F_image_t mnt( 10, 10 ), mne( 10, 10 ); fill_pixels( view( mns ), gray16s_image_t::value_type( 12 )); fill_pixels( view( mnt ), gray32F_image_t::value_type( 5 )); fill_pixels( view( mne ), gray32F_image_t::value_type( 0 )); auto fun = generate_diff< gray16s_image_t::value_type , gray32F_image_t::value_type , gray32F_image_t::value_type >; transform_pixels( view(mne), view(mns), view(mnt), fun ); return 0; } Next I'll try dynamic_image. Regards, Christian
Hi Olivier, there is no transform_pixels for any_image. That's a bit odd since there are other STL algorithms. I'll try my best to create one but it might take a bit. I'll let you know. Christian
Hi Olivier, here is a slightly better version: #include <boost\gil\gil_all.hpp> #include <boost\gil\extension\dynamic_image\dynamic_image_all.hpp> #include <boost\gil\extension\numeric\pixel_numeric_operations.hpp> namespace boost { namespace gil { template <typename Channel1,typename Channel2,typename ChannelR> struct channel_abs_t : public std::binary_function<Channel1,Channel2,ChannelR> { ChannelR operator()(typename channel_traits<Channel1>::const_reference ch1, typename channel_traits<Channel2>::const_reference ch2) const { return std::abs( ChannelR(ch1) - ChannelR(ch2) ); } }; template <typename PixelRef1, // models pixel concept typename PixelRef2, // models pixel concept typename PixelR> // models pixel value concept struct pixel_abs_t { PixelR operator() (const PixelRef1& p1, const PixelRef2& p2) const { PixelR result; static_transform(p1,p2,result, channel_abs_t<typename channel_type<PixelRef1>::type, typename channel_type<PixelRef2>::type, typename channel_type<PixelR>::type>()); return result; } }; typedef double bits64F; GIL_DEFINE_BASE_TYPEDEFS(64F,gray) typedef float bits32F; GIL_DEFINE_BASE_TYPEDEFS(32F,gray) } // namespace gil } // namespace boost using namespace boost; using namespace gil; template< typename SRC1, typename SRC2, typename DST > void generate_diff( const SRC1& src1, const SRC2& src2, const DST& dst ) { transform_pixels( src1, src2, dst, pixel_abs_t< typename SRC1::value_type , typename SRC2::value_type , typename DST::value_type >() ); } int main(int argc, char** argv) { { gray16s_image_t mns( 10, 10 ); gray32F_image_t mnt( 10, 10 ), mne( 10, 10 ); fill_pixels( view( mns ), gray16s_image_t::value_type( 5 )); fill_pixels( view( mnt ), gray32F_image_t::value_type( 12 )); fill_pixels( view( mne ), gray32F_image_t::value_type( 0 )); generate_diff( const_view( mns ), const_view( mnt ), view( mne ) ); gray32F_image_t::value_type p = *view( mne ).xy_at( 0, 0 ); } return 0; } Does that somehow fit your needs? Regards, Christian
participants (2)
-
Christian Henning
-
Olivier Tournaire