$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
recorder.hh
1 // Copyright (C) 2011, 2012 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef APPS_MORPHERS_RECORDER_HH
27 # define APPS_MORPHERS_RECORDER_HH
28 
34 
35 #include <sstream>
36 #include <iomanip>
37 
38 #include <string>
39 
40 #include <mln/trait/ch_value.hh>
41 
42 #include <mln/core/image/imorph/decorated_image.hh>
43 
44 #include <mln/value/rgb8.hh>
45 
46 #include <mln/core/routine/duplicate.hh>
47 
48 #include <mln/io/ppm/save.hh>
49 
50 #include "apps/data.hh"
51 
52 
53 // Forward declaration.
54 template <typename I> struct recorder;
55 
56 /* FIXME: mln::decorated_image lacks a proper definition of
57  properties! (see mln/core/image/imorph/decorated_image.hh). We use
58  the following (minimal) set of properties as a workaround for the
59  recorder decoration. */
60 namespace mln
61 {
62  namespace trait
63  {
64 
65  template <typename I>
66  struct image_< decorated_image< I, recorder<I> > >
67  : default_image_morpher< I,
68  mln_value(I),
69  decorated_image< I, recorder<I> > >
70  {
71  typedef trait::image::category::identity_morpher category;
72 
73  // Prevent fast processing of images requiring a specific
74  // interface that we are unable to retrieve now.
75  typedef trait::image::value_storage::disrupted value_storage;
76  };
77 
78  } // end of namespace mln::trait
79 
80 } // end of namespace mln
81 
82 
83 // Recorder.
84 template <typename I>
85 struct recorder
86 {
87  void reading(const I&, const mln_psite(I)&) const
88  {
89  // N/A.
90  }
91 
92  void writing(I& ima, const mln_psite(I)&, const mln_value(I)&)
93  {
94  sequence.push_back(mln::duplicate(ima));
95  }
96 
97  std::vector<mln_concrete(I)> sequence;
98 };
99 
100 /* Skeleton of an image decorated with a recorder.
101 
102  Initialy, I (Roland) wanted to add this to mln/trait/ch_value.hh:
103 
104  template < template <class, class> class M, typename I, typename D,
105  typename V >
106  struct ch_value_< M< tag::image_<I>, tag::data_<D> >, V >
107  {
108  typedef M< mln_ch_value(I, V), D > ret;
109  };
110 
111  However, this would not work in the case of the recorder since the
112  type D of the data attached to the image (of type I) has to be
113  changed as well. Indeed the initial decoration contains a sequence
114  of images of type I, which should be changed into a sequence of
115  images of type mln_ch_value(I, V).
116 
117  There are several option to improve this. One is to create a
118  ch_value trait for data/decorations such as `recorder<I>'. Another
119  one is to refine the skeleton of decorated_image<I, D> to have it
120  convey the type the data stored in the decoration, e.g, changing
121 
122  typedef decorated_image< tag::image_<I>, tag::data_<D> > skeleton;
123 
124  into something like
125 
126  typedef decorated_image< tag::image_<I>, tag::data_<D, V> > skeleton;
127 
128  but this seems overly complicated.
129 
130  The workaround chosen here is very local, and address the very
131  specific case of decorated_image< I, recorder<I> >. */
132 
133 namespace mln
134 {
135  namespace trait
136  {
137  namespace impl
138  {
139  template < typename I, typename V >
140  struct ch_value_< decorated_image< tag::image_<I>,
141  tag::data_< recorder<I> > >,
142  V >
143  {
144  typedef decorated_image< mln_ch_value(I, V),
146  };
147  } // end namespace mln::trait::impl
148 
149  } // end namespace mln::trait
150 
151 } // end namespace mln
152 
153 // Helper.
154 template <typename I>
155 inline
157 record(mln::Image<I>& ima)
158 {
159  return mln::decorate(ima, recorder<I>());
160 }
161 
162 
163 // I/O.
164 namespace ppm
165 {
166  template <typename I>
167  inline
168  void
170  const std::string& prefix)
171  {
172  for (size_t i = 0; i < rec.decoration().sequence.size(); ++i)
173  {
174  std::stringstream s;
175  s << std::setfill ('0') << std::setw (6) << i;
176  mln::io::ppm::save(rec.decoration().sequence[i],
177  prefix + s.str() + ".ppm");
178  }
179  }
180 }
181 
182 #endif // ! APPS_MORPHERS_RECORDER_HH