iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Layout.H
Go to the documentation of this file.
1 /*! @file
2  @author Laurent Itti
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 #ifndef INCLUDE_NRT_CORE_IMAGE_LAYOUT_H
37 #define INCLUDE_NRT_CORE_IMAGE_LAYOUT_H
38 
39 #include <nrt/Core/Image/Image.H>
41 #include <vector>
42 
43 namespace nrt
44 {
45  /*! \defgroup imagelayout Layout class and functions to build tiled layouts of images
46 
47  The Layout class provides easy and efficient ways to create composite displays by tiling together several images
48  of possibly different sizes.
49 
50  A Layout is just a graph where leaf nodes are Image objects, and non-leaf nodes are Layout objects that specify
51  either a horizontal or a vertical adjacency relationship. The Layout thus indicates which Image or Layout is next
52  to which other Layout or Image. After a Layout has been assembled, it can be rendered into a result
53  Image. Specifying a complex arrangement of images in this way is very natural yet more efficient than in using
54  multiple successive concatenations of images (e.g., pace an image above another one, then add another image to the
55  left of that group, etc), as each of these successive concatenations requires allocating a new image and copying
56  pixel data into it. Rendering a Layout is done in one step, by first computing the final size of the concatenation
57  and the coordinates of each of the leaf images, then allocating the final image, and finally pasting each leaf
58  Image into its desired position.
59 
60  \ingroup imagerel */
61 
62  /*! @{ */ // **********************************************************************
63 
64  //! Direction of a Layout
65  enum class LayoutDir {
66  H, //!< Horizontal
67  V //!< Vertical
68  };
69 
70  //! Represents tiled layouts of arbitrary numbers of images of different sizes
71  /*! If you want to build up a big image of different individual images (e.g., for display), you have three basic
72  choices:
73 
74  - use a series of nested concatX() and concatY() calls, which is convenient syntactically but is inefficient
75  because each pixel is copied multiple times, once for each concat call.
76 
77  - make a single output image and use a series of inplacePaste() or inplaceEmbed() calls to put the various pieces
78  in place; this is efficient but requires manual tabulation of the various corner locations of the different
79  tiles.
80 
81  - with the Layout class, we get both efficiency and syntactical convenience. Instead of concatX() and concatY(),
82  we use hcat() and vcat() which construct Layout objects (with arbitrary nesting); none of these calls involves
83  any pixel copying. Instead we just keep track of the tile structure that is desired. Then when the final Layout
84  has been constructed, it can be rendered into an Image in a single pass with the render() call.
85 
86  For example, where previously you would have done
87 
88  @code
89  nrt::Image<nrt::PixGray<nrt::byte>> = concatX(e, concatY(concatX(a,b), concatX(c,d)));
90  @endcode
91 
92  now with Layout you would do
93 
94  @code
95  nrt::Image<nrt::PixGray<nrt::byte>> = hcat(e, vcat(hcat(a,b), hcat(c,d))).render();
96  @endcode */
97  template <class T>
98  class Layout
99  {
100  public:
101  //! Default constructor, no image, no dims, just a direction
103 
104  //! Construct from just one image
106 
107  //! Construct from two other Layout objects
108  Layout(nrt::Layout<T> const & p1, nrt::Layout<T> const & p2, nrt::LayoutDir const d);
109 
110  //! Construct from an ImageSet
111  Layout(nrt::ImageSet<T> const & imgs, nrt::LayoutDir const d);
112 
113  //! Construct from a vector of Layout objects
114  Layout(std::vector<Layout<T> > const & layouts, nrt::LayoutDir const d);
115 
116  //! Returns true if we have no image yet
117  bool empty() const;
118 
119  //! Returns the dims of the image that would be created by render()
120  nrt::Dims<int32> const & dims() const;
121 
122  //! Returns the width of the image that would be created by render()
123  int32 width() const;
124 
125  //! Returns the height of the image that would be created by render()
126  int32 height() const;
127 
128  //! Returns our direction
129  LayoutDir dir() const;
130 
131  //! Returns our size, i.e., our number of parts
132  int32 size() const;
133 
134  //! Return a part
135  Layout<T> const & part(int32 const i) const;
136 
137  //! Return our leaf Image
138  nrt::Image<T> leaf() const;
139 
140  //! Render into an Image, using black as background color
141  nrt::Image<T> render() const;
142 
143  //! Render into an Image, using supplied background color
144  nrt::Image<T> render(T const & bgcol) const;
145 
146  //! Render into an existing Image
147  void renderInto(Image<T> & x, Point2D<int> const & p) const;
148 
149  private:
150  // NOTE: this implementation make sizeof(Layout)==32 on a 32-bit machine; if this becomes a problem it may be
151  // possible to reduce the footprint with some optimization tricks (such as: use a custom linked list instead of
152  // the std::vector<>; condense itsLeafImg and itsRenderCache into a single image; replace itsDir with a single-bit
153  // bitfield)
154 
155  std::vector<Layout<T> > itsParts;
156  Image<T> itsLeafImg;
157  LayoutDir itsDir;
158  Dims<int32> itsDims;
159  mutable Image<T> itsRenderCache;
160  };
161 
162  // ######################################################################
163  //! Convenience free functions for horizontal Layout concatenation
164  /*! @{ */
165 
166  //! Horizontally concatenate two Image objects
167  template <class T> inline
169 
170  //! Horizontally concatenate an Image and a Layout
171  template <class T> inline
172  Layout<T> hcat(nrt::Image<T> p1, Layout<T> const & p2);
173 
174  //! Horizontally concatenate a Layout and an Image
175  template <class T> inline
176  Layout<T> hcat(Layout<T> const & p1, nrt::Image<T> p2);
177 
178  //! Horizontally concatenate two Layout objects
179  template <class T> inline
180  Layout<T> hcat(Layout<T> const & p1, Layout<T> const & p2);
181 
182  //! Horizontally concatenate three Layout objects
183  template <class T> inline
184  Layout<T> hcat(Layout<T> const & p1, Layout<T> const & p2, Layout<T> const & p3);
185 
186  //! Horizontally concatenate a set of Image objects
187  template <class T> inline
188  Layout<T> hcat(nrt::ImageSet<T> const imgs);
189 
190  /*! @} */
191 
192  // ######################################################################
193  //! Convenience functions for vertical Layout concatenation
194 
195  /*! @{ */
196 
197  //! Vertically concatenate two Image objects
198  template <class T> inline
200 
201  //! Vertically concatenate an Image and a Layout
202  template <class T> inline
203  Layout<T> vcat(nrt::Image<T> p1, Layout<T> const & p2);
204 
205  //! Vertically concatenate a Layout and an Image
206  template <class T> inline
207  Layout<T> vcat(Layout<T> const & p1, nrt::Image<T> p2);
208 
209  //! Vertically concatenate two Layout objects
210  template <class T> inline
211  Layout<T> vcat(Layout<T> const & p1, Layout<T> const & p2);
212 
213  //! Vertically concatenate three Layout objects
214  template <class T> inline
215  Layout<T> vcat(Layout<T> const & p1, Layout<T> const & p2, Layout<T> const & p3);
216 
217  //! Vertically concatenate a set of Image objects
218  template <class T> inline
219  Layout<T> vcat(nrt::ImageSet<T> const imgs);
220 
221  /*! @} */
222 
223  // ######################################################################
224  //! Convenience functions for combination h/v array Layout concatenation
225 
226  /*! @{ */
227 
228  //! Concatenate a set of images into a grid
229  /*! The concatenation runs from left to right, and top to bottom.
230  @param imgs Images to concatenate
231  @param nx number of images in each horizontal row */
232  template <class T> inline
233  Layout<T> arrcat(nrt::ImageSet<T> imgs, int32 const nx);
234 
235  /*! @} */
236 
237 
238  /*! @} */ // **********************************************************************
239 
240 } // namespace nrt
241 
242 // include our implementation details
244 
245 #endif // INCLUDE_NRT_CORE_IMAGE_LAYOUT_H