1 // Copyright (C) 2013 Carnë Draug <carandraug@octave.org>
2 //
3 // This program is free software; you can redistribute it and/or modify it under
4 // the terms of the GNU General Public License as published by the Free Software
5 // Foundation; either version 3 of the License, or (at your option) any later
6 // version.
7 //
8 // This program is distributed in the hope that it will be useful, but WITHOUT
9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11 // details.
12 //
13 // You should have received a copy of the GNU General Public License along with
14 // this program; if not, see <http://www.gnu.org/licenses/>.
15 
16 // This is wrapper class for the @strel class so that it can be used by
17 // the rest of the image package using SE's. It's not a perfect wrapper
18 // on purpose. For example, the reflect method behaves kinda weird for
19 // matlab compatibility. In here we try to make a bit more sense.
20 
21 // An important thing about this class is how the origin (defaults to
22 // center coordinates which can have different interpretations when
23 // sides are of even length) moves when it's reflected. Consider the
24 // following (x is the origin)
25 //
26 //  o o o                   o o o
27 //  o x o  -- reflect -->   o x o
28 //  o o o                   o o o
29 //
30 //  o o o o                   o o o o
31 //  o o x o  -- reflect -->   o x o o
32 //  o o o o                   o o o o
33 
34 
35 #ifndef OCTAVE_IMAGE_STREL
36 #define OCTAVE_IMAGE_STREL
37 
38 #include <vector>
39 #include <string>
40 
41 #include <octave/Array.h>
42 #include <octave/dNDArray.h>
43 #include <octave/dim-vector.h>
44 #include <octave/boolNDArray.h>
45 
46 #include <octave/ov.h>
47 
48 namespace octave
49 {
50   namespace image
51   {
52     class strel
53     {
54       public:
55         explicit strel (const octave_value& arg);
56         strel (const boolNDArray& nhood, const NDArray& height);
57         strel (const boolNDArray& nhood, const NDArray& height,
58                const Array<octave_idx_type>& origin);
59 
60         boolNDArray             get_nhood (void) const;
61         octave_idx_type         get_nnz (void) const;
62         Array<octave_idx_type>  get_origin (void) const;
63         strel                   operator () (const octave_idx_type& i) const;
64 
65         // Number of strel objects after decomposition, NOT numel of nhood
66         octave_idx_type         numel (void) const;
67 
68         // flat SE?
69         bool flat (void) const;
70 
71         // set origin of the SE to specific coordinates
72         void set_origin (const Array<octave_idx_type>& sub);
73 
74         // reflect the SE (rotates is 180 degrees in all dimensions).
75         // Note that when rotating it, the origin coordinates move with it
76         // (this is by design see ratinoal on top of this file).
77         strel reflect (void) const;
78 
79         // given a matrix with a specific cumulative size, what's the offset
80         // for each true element of the nhood from the first element (true or
81         // false) of the nhood.
82         Array<octave_idx_type> offsets (const dim_vector& cum_size) const;
83 
84         // array with height of each true element in the nhood (same order
85         // as the one returned by offsets).
86         template<class P>
87         Array<P> true_heights (void) const;
88 
89         Array<octave_idx_type> pre_pad  (const octave_idx_type& mt_ndims,
90                                          const std::string& shape) const;
91         Array<octave_idx_type> post_pad (const octave_idx_type& mt_ndims,
92                                          const std::string& shape) const;
93 
94       private:
95         boolNDArray             nhood;
96         NDArray                 height;
97         octave_idx_type         nnz;
98         Array<octave_idx_type>  origin;
99         dim_vector              size;
100         octave_idx_type         ndims;
101         std::vector<strel>      decomposition;
102 
103         void ini_ctor (void);
104 
105         Array<octave_idx_type> default_origin (void);
106 
107         void end_ctor (void);
108 
109         void validate_origin (void);
110 
111     };
112   }
113 }
114 
115 // Define it on header or we we need to instantiate it for all
116 // possible classes in strel.cc
117 template<class P>
118 Array<P>
true_heights(void)119 octave::image::strel::true_heights (void) const
120 {
121   Array<P> true_heights (dim_vector (nnz, 1));
122   for (octave_idx_type ind = 0, found = 0; found < nnz; ind++)
123     if (nhood(ind))
124       true_heights(found++) = height(ind);
125   return true_heights;
126 }
127 
128 #endif
129