00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef OLENA_TOPO_INTER_PIXEL_INTER_PIXEL_HH
00029 # define OLENA_TOPO_INTER_PIXEL_INTER_PIXEL_HH
00030
00031 # include <oln/basics.hh>
00032 # include <oln/topo/inter-pixel/node.hh>
00033 # include <oln/topo/inter-pixel/fwd-dir-iter.hh>
00034 # include <oln/topo/inter-pixel/bkd-dir-iter.hh>
00035
00036 # include <ntg/basics.hh>
00037
00038 namespace oln {
00039
00040 namespace topo {
00041
00042 namespace inter_pixel {
00044 # define oln_interpixel_type(ImgType) \
00045 typename oln::mute< ImgType, oln_node_type(ImgType) >::ret
00046
00074 template <class I>
00075 class interpixel
00076 {
00077 public:
00078 typedef oln_dpoint_type(I) dpoint_type;
00079 typedef oln_point_type(I) point_type;
00080 typedef oln_node_type(I) node_type;
00081 typedef oln_fwd_dir_iter_type(I) fwd_dir_iter_type;
00082 typedef oln_bkd_dir_iter_type(I) bkd_dir_iter_type;
00083 typedef oln_dir_type(I) dir_type;
00084 typedef oln_dir_traits_type(I) dir_traits_type;
00085 typedef oln_head_type(I) head_type;
00086 typedef oln_interpixel_type(I) inter_pixel_type;
00087
00088 public:
00090 interpixel(const I & img) :
00091 data_(img.nrows() + 1, img.ncols() + 1)
00092 {
00093
00094
00095 img.border_adapt_assign(1, ntg_max_val(oln_value_type(I)));
00096
00097 oln_iter_type(inter_pixel_type) p(data_);
00098 fwd_dir_iter_type it;
00099
00100 for_all(p)
00101 {
00102 for_all(it)
00103 if (img[p + neighb_[it]] != img[p + neighb_[it.next()]])
00104 data_[p].set(it);
00105 }
00106 }
00107
00109 const node_type
00110 operator[](const point_type & p) const
00111 {
00112 return data_[p];
00113 }
00114
00119 head_type
00120 folw(const head_type& in) const
00121 {
00122 precondition(data_[in.first].get(in.second) == true);
00123
00124 head_type out = in;
00125
00126 do
00127 {
00128 out.first += inter_neighb_[out.second];
00129
00130 if (out.first == in.first || data_[out.first].rank() > 2)
00131 {
00132 out.second = dir_traits_type::opposite(out.second);
00133 break;
00134 }
00135
00136 dir_type next = dir_traits_type::next(out.second);
00137 dir_type prev = dir_traits_type::prev(out.second);
00138
00139 out.second = data_[out.first].get(next) ? next :
00140 data_[out.first].get(prev) ? prev : out.second;
00141 }
00142 while (out.first != in.first);
00143
00144 return out;
00145 }
00146
00148 std::ostream&
00149 print(std::ostream & ostr) const
00150 {
00151 oln_iter_type(inter_pixel_type) p(data_);
00152
00153 for_all(p)
00154 if (data_[p].rank() > 2)
00155 {
00156 ostr << p << ":";
00157
00158 fwd_dir_iter_type it;
00159 for_all(it)
00160 if (data_[p].get(it))
00161 ostr << " " << it;
00162
00163 ostr << std::endl;
00164 }
00165
00166 return ostr;
00167 }
00168
00169 private:
00170 inter_pixel_type data_;
00171
00172 public:
00173 static const dpoint_type neighb_[4];
00174 static const dpoint_type inter_neighb_[4];
00175 };
00176
00177 }
00178
00179 }
00180
00181 }
00182
00183 template <class I>
00184 inline std::ostream & operator<<(std::ostream & ostr,
00185 const oln::topo::inter_pixel::interpixel<I> & ip)
00186 {
00187 return ip.print(ostr);
00188 }
00189
00190 template <class I>
00191 const oln_dpoint_type(I)
00192 oln::topo::inter_pixel::interpixel<I>::neighb_[4] = {oln_dpoint_type(I)(0,0),
00193 oln_dpoint_type(I)(-1,0),
00194 oln_dpoint_type(I)(-1,-1),
00195 oln_dpoint_type(I)(0,-1)};
00196 template <class I>
00197 const oln_dpoint_type(I)
00198 oln::topo::inter_pixel::interpixel<I>::inter_neighb_[4] = {oln_dpoint_type(I)(0,1),
00199 oln_dpoint_type(I)(-1,0),
00200 oln_dpoint_type(I)(0,-1),
00201 oln_dpoint_type(I)(1,0)};
00202
00203 #endif // ! OLENA_TOPO_INTER_PIXEL_INTER_PIXEL_HH