TuttleOFX
1
|
00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://opensource.adobe.com/licenses.html) 00005 */ 00006 00007 /*************************************************************************************************/ 00008 00009 #ifndef _TERRY_NUMERIC_KERNEL_HPP_ 00010 #define _TERRY_NUMERIC_KERNEL_HPP_ 00011 00012 /*! 00013 /// \file 00014 /// \brief Definitions of 1D fixed-size and variable-size kernels and related operations 00015 /// \author Hailin Jin and Lubomir Bourdev \n 00016 /// Adobe Systems Incorporated 00017 /// \date 2005-2007 \n Last updated on September 26, 2006 00018 */ 00019 00020 00021 #include <boost/gil/gil_config.hpp> 00022 #include <boost/gil/utilities.hpp> 00023 00024 #include <boost/array.hpp> 00025 #include <boost/mpl/bool.hpp> 00026 00027 #include <cstddef> 00028 #include <cassert> 00029 #include <algorithm> 00030 #include <vector> 00031 #include <memory> 00032 00033 namespace terry { 00034 namespace filter { 00035 00036 using namespace boost::gil; 00037 00038 namespace detail { 00039 00040 /// \brief kernel adaptor for one-dimensional cores 00041 /// Core needs to provide size(),begin(),end(),operator[], 00042 /// value_type,iterator,const_iterator,reference,const_reference 00043 template <typename Core> 00044 class kernel_1d_adaptor : public Core { 00045 private: 00046 std::size_t _center; 00047 public: 00048 kernel_1d_adaptor() : _center(0) {} 00049 explicit kernel_1d_adaptor(std::size_t center_in) : _center(center_in) {assert(_center<this->size());} 00050 kernel_1d_adaptor(std::size_t size_in,std::size_t center_in) : 00051 Core(size_in), _center(center_in) {assert(_center<this->size());} 00052 kernel_1d_adaptor(const kernel_1d_adaptor& k_in) : Core(k_in), _center(k_in._center) {} 00053 00054 kernel_1d_adaptor& operator=(const kernel_1d_adaptor& k_in) { 00055 Core::operator=(k_in); 00056 _center=k_in._center; 00057 return *this; 00058 } 00059 std::size_t left_size() const {assert((_center<this->size()) || (this->size()==0));return _center;} 00060 std::size_t right_size() const {assert((_center<this->size()) || (this->size()==0));return this->size()?this->size()-_center-1:0;} 00061 std::size_t& center() {return _center;} 00062 const std::size_t& center() const {return _center;} 00063 void set_center( const std::size_t center ) { _center = center; } 00064 }; 00065 00066 } // namespace detail 00067 00068 /// \brief variable-size kernel 00069 template <typename T, typename Alloc = std::allocator<T> > 00070 class kernel_1d : public detail::kernel_1d_adaptor<std::vector<T,Alloc> > { 00071 typedef detail::kernel_1d_adaptor<std::vector<T,Alloc> > parent_t; 00072 public: 00073 typedef T value_type; 00074 typedef boost::mpl::false_ is_fixed_size_t; 00075 public: 00076 kernel_1d() {} 00077 kernel_1d(std::size_t size_in,std::size_t center_in) : parent_t(size_in,center_in) {} 00078 template <typename FwdIterator> 00079 kernel_1d(FwdIterator elements, std::size_t size_in, std::size_t center_in) : parent_t(size_in,center_in) { 00080 boost::gil::detail::copy_n(elements,size_in,this->begin()); 00081 } 00082 kernel_1d(const kernel_1d& k_in) : parent_t(k_in) {} 00083 }; 00084 00085 /// \brief static-size kernel 00086 template <typename T,std::size_t Size> 00087 class kernel_1d_fixed : public detail::kernel_1d_adaptor<boost::array<T,Size> > { 00088 typedef detail::kernel_1d_adaptor<boost::array<T,Size> > parent_t; 00089 public: 00090 typedef T value_type; 00091 typedef boost::mpl::true_ is_fixed_size_t; 00092 public: 00093 kernel_1d_fixed() {} 00094 explicit kernel_1d_fixed(std::size_t center_in) : parent_t(center_in) {} 00095 00096 template <typename FwdIterator> 00097 explicit kernel_1d_fixed(FwdIterator elements, std::size_t center_in) : parent_t(center_in) { 00098 boost::gil::detail::copy_n(elements,Size,this->begin()); 00099 } 00100 kernel_1d_fixed(const kernel_1d_fixed& k_in) : parent_t(k_in) {} 00101 }; 00102 00103 /// \brief reverse a kernel 00104 template <typename Kernel> 00105 inline Kernel reverse_kernel(const Kernel& kernel) { 00106 Kernel result(kernel); 00107 result.center()=kernel.right_size(); 00108 std::reverse(result.begin(), result.end()); 00109 return result; 00110 } 00111 00112 00113 } 00114 } 00115 00116 #endif