• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

2008__tour3.cc

00001 // Copyright (C) 2001, 2007, 2008 EPITA Research and Development
00002 // Laboratory
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
00026 
00027 // File: tour2.cc.
00028 
00029 #include <oln/core/2d/image2d.hh>
00030 #include <oln/core/2d/neighb2d.hh>
00031 
00032 #include <oln/core/gen/such_as.hh>
00033 #include <oln/core/gen/torus_image.hh>
00034 #include <oln/core/gen/pw_value.hh>
00035 #include <oln/core/gen/fun_ops.hh>
00036 
00037 #include <oln/data/fill.hh>
00038 #include <oln/debug/fill.hh>
00039 #include <oln/debug/println.hh>
00040 
00041 
00042 // Note to the reader: you should have read the files tour1.cc and
00043 // tour2.cc before starting with this present file.
00044 
00045 
00046 
00047 // We have encapsulated an algorithm into a procedure which is forward
00048 // declared below so that it can be used in the section 'main'.
00049 template <typename I> void algo(const I& img);
00050 
00051 
00052 // Some functions that will be useful in the following:
00053 bool chessboard(oln::point2d p)
00054 {
00055   return (p.row() + p.col()) % 2;
00056 }
00057 
00058 
00059 
00060 int main()
00061 {
00062   using namespace oln;
00063 
00064   // First our domain is 2d box:
00065   box2d b(point2d(0, 0), point2d(2, 2));
00066   //              ^^^^           ^^^^
00067   //              from            to
00068 
00069   // We define a binary image with values on that box.
00070   image2d<bool> img(b);
00071 
00072   // With an array of Booleans (1 means true, 0 means false)...
00073   bool vals[] = { 1, 0, 0,
00074                   0, 1, 0,
00075                   0, 1, 1 };
00076   // ...the debug::fill routine allows for manually initializing
00077   // image data:
00078   debug::fill(img, vals);
00079   std::cout << "img = " << std::endl;
00080   debug::println(img);
00081   // img =
00082   // | - - 
00083   // - | - 
00084   // - | | 
00085 
00086   image2d<int> ima(b);          // An image of integers with the same
00087   box2d::piter p(ima.points()); // domain as img...
00088   int i = 0;
00089   for_all(p)
00090     ima(p) = i++; // ...and manually filled with values.
00091 
00092   std::cout << "ima = " << std::endl;
00093   debug::println(ima);
00094   // ima = 
00095   // 0 1 2 
00096   // 3 4 5 
00097   // 6 7 8 
00098 
00099 
00100 
00101   // The algorithm defined at the end of this file is very close to
00102   // the one of the tour former file.  The major difference is that it
00103   // does not rely on a window but on a neighborhood.
00104 
00105   // In image processing, we usually say that "an image has a given
00106   // neighborhood" or that "we associate/embed a neighborhood to/into
00107   // an image". In Olena, that is really the case: the image can
00108   // "have" a neighborhood, meaning that a neighborhood can be added
00109   // to an image in order to obtain an "image with a neighborhood".
00110 
00111   // Joining an image with a neighborhood is performed with the
00112   // operator '+':
00113   algo(ima + c4);  // c4 is the 2D neighborhood corresponding to
00114                    // 4-connectivity; such as many classical
00115                    // neighborhoods it is provided by Olena.
00116   // The result is given below.
00117 
00118   // ---input:
00119   // 0 1 2 
00120   // 1 2 3 
00121   // 2 3 4 
00122   // ---output:
00123   // 0: 1 1
00124   // 1: 0 2 2
00125   // 2: 1 3
00126   // 1: 0 2 2
00127   // 2: 1 1 3 3
00128   // 3: 2 2 4
00129   // 2: 1 3
00130   // 3: 2 2 4
00131   // 4: 3 3
00132 
00133   // That was expectable...
00134 
00135 
00136   // And now for a little test: what is the result of this code?
00137   {
00138     image2d<int> test(ima.points());
00139     data::fill(test, ima);
00140     (test + c4).at(1, 1) = 9;
00141     debug::println(test);
00142   }
00143   // and can you tell why?
00144   // The answers are given in the file tour3-test.txt
00145 
00146 
00147   // Now let us start experimenting the genericity of Olena!
00148 
00149 
00150   // First, imagine that you want to restrict the domain of ima to a
00151   // subset of points, a region or whatever.  For instance, the
00152   // chessboard function takes a point as argument and returns a
00153   // Boolean so it is like a predicate.  We can want to consider only
00154   // the points of ima "such as" this predicate is verified.  The
00155   // "such as" mathematical symbol is '|' so let's rock:
00156 
00157   algo((ima | chessboard) + c8);
00158   // gives:
00159 
00160   // ---input:
00161   //   1   
00162   // 3   5 
00163   //   7   
00164   // ---output:
00165   // 1: 3 5
00166   // 3: 1 7
00167   // 5: 1 7
00168   // 7: 3 5
00169 
00170   // where the blanks in printing the input image denote that the
00171   // corresponding points do NOT belong to the image domain.
00172 
00173   // Another similar example is based on the binary image created at
00174   // the beginning of this tour:
00175   algo((ima | img) + c8);
00176   // which gives:
00177 
00178   // ---input:
00179   // 0     
00180   //   4   
00181   //   7 8 
00182   // ---output:
00183   // 0: 4
00184   // 4: 0 7 8
00185   // 7: 4 8
00186   // 8: 4 7
00187 
00188 
00189 
00190   // Second, imagine that you want your initial image to get the
00191   // geodesy of a torus, that is, a 2D image wrapped on a torus.
00192   // Points located at the image boundary have neighbors; for
00193   // instance, the point denoted by the 'x' cross below has for
00194   // 4-connectivity neighbors: t, l, r, and b (respectively for top,
00195   // left, right, and bottom):
00196 
00197   // b o o o
00198   // o o o o
00199   // t o o o
00200   // x r o l
00201 
00202   // Let us try:
00203   algo(torus(ima) + c8); 
00204   // gives:
00205 
00206   // ---input:
00207   // 0 1 2 
00208   // 3 4 5 
00209   // 6 7 8 
00210   // ---output:
00211   // 0: 8 6 7 2 1 5 3 4
00212   // 1: 6 7 8 0 2 3 4 5
00213   // 2: 7 8 6 1 0 4 5 3
00214   // 3: 2 0 1 5 4 8 6 7
00215   // 4: 0 1 2 3 5 6 7 8
00216   // 5: 1 2 0 4 3 7 8 6
00217   // 6: 5 3 4 8 7 2 0 1
00218   // 7: 3 4 5 6 8 0 1 2
00219   // 8: 4 5 3 7 6 1 2 0
00220 
00221 
00222 
00223   // We can have both the torus geodesy and a sub-domain:
00224 
00225   algo(torus(ima | chessboard) + c8);
00226   algo(torus(ima | img) + c8);
00227 
00228   // which respectively give:
00229 
00230   // ---input:
00231   //   1   
00232   // 3   5 
00233   //   7   
00234   // ---output:
00235   // 1: 7 3 5
00236   // 3: 1 5 7
00237   // 5: 1 3 7
00238   // 7: 3 5 1
00239 
00240   // and:
00241   
00242   // ---input:
00243   // 0     
00244   //   4   
00245   //   7 8 
00246   // ---output:
00247   // 0: 8 7 4
00248   // 4: 0 7 8
00249   // 7: 4 8 0
00250   // 8: 4 7 0
00251 
00252 
00253 
00254 
00255   // Last, the way a predicate is defined can also rely on some image
00256   // values.  For that the user can on the fly provide an expression
00257   // built with the "pw_value" facility, where "pw_" means
00258   // "point-wise" for short:
00259 
00260   algo((ima | (pw_value(ima) < 4)) + c4);
00261 
00262   // In this example, "pw_value(ima)" is the function that represents
00263   // the point-wise value of the 'ima' image, that is, the function
00264   // "p -> ima(p)".  This naturally leads to:
00265 
00266   // ---input:
00267   // 0 1 2 
00268   // 3     
00269   // 
00270   // ---output:
00271   // 0: 1 3
00272   // 1: 0 2
00273   // 2: 1
00274   // 3: 0
00275 
00276 
00277 
00278   // From those examples, you should realize that:
00279 
00280 
00281   //  +-----------------------------------------------------------+
00282   //  |                                                           |
00283   //  |  The level of "genericity" provided by Olena is rather    |
00284   //  |  high; it means:                                          |
00285   //  |                                                           |
00286   //  |  - taking the image dimension you work on;                |
00287   //  |                                                           |
00288   //  |  - having the type of pixel values you need;              |
00289   //  |                                                           |
00290   //  |  - choosing the neighborhood you want;                    |
00291   //  |                                                           |
00292   //  |  - changing the geodesy if you need it;                   |
00293   //  |                                                           |
00294   //  |  - being able to restrict the image domain;               |
00295   //  |                                                           |
00296   //  |  - and many other features that are addressed further     |
00297   //  |    in the tour...                                         |
00298   //  |                                                           |
00299   //  +-----------------------------------------------------------+
00300 
00301 }
00302 
00303 
00304 
00305 
00306 
00307 // The algorithm 'algo':
00308 
00309 template <typename I>
00310 void algo(const I& img)
00311 {
00312   std::cout << "---input:" << std::endl;
00313   oln::debug::print(img);
00314   std::cout << "---output:" << std::endl;
00315 
00316   oln_piter(I) p(img.points()); // p iterates on img points
00317   oln_niter(I) n(img, p);       // n iterates in img on neighbors of p
00318 
00319   for_all(p)
00320     {
00321       std::cout << oln::debug::format(img(p))
00322                 << ':';
00323       for_all(n)
00324         std::cout << ' '
00325                   << oln::debug::format(img(n));
00326       std::cout << std::endl;
00327     }
00328 
00329   std::cout << std::endl;
00330 }

Generated on Tue Oct 4 2011 15:23:23 for Milena (Olena) by  doxygen 1.7.1