iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MorphologyImpl.H
Go to the documentation of this file.
1 /*! @file
2  @author Pezhman Firoozfam
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_IMAGEPROC_FILTERING_DETAILS_MORPHOLOGYIMPL_H
37 #define INCLUDE_NRT_IMAGEPROC_FILTERING_DETAILS_MORPHOLOGYIMPL_H
38 
39 namespace nrt
40 {
41 
42 // ######################################################################
43 template <class T>
44 Image<T> dilate(Image<T> const& img, Image<T> const& se, Point2D<int> origin)
45 {
46  int const iw = img.width(); int const ih = img.height();
47  int const sw = se.width(); int const sh = se.height();
48 
49  if (origin == Point2D<int>(-1,-1))
50  {
51  origin.x() = (sw - 1) / 2;
52  origin.y() = (sh - 1) / 2;
53  }
54 
55  Image<T> result(iw, ih, ImageInitPolicy::Zeros);
56 
57  typename Image<T>::const_iterator iptr, sptr1, sptr2;
58  typename Image<T>::iterator rptr1, rptr2;
59  iptr = img.begin();
60 
61  for (int iy = 0; iy < ih; ++iy)
62  {
63  // initialize height
64  int rYstart = iy - origin.y();
65  int rYend = rYstart + sh;
66  int sYstart = 0;
67  if (rYstart < 0)
68  {
69  sYstart -= rYstart;
70  rYstart = 0;
71  }
72  if (rYend > ih) rYend = ih;
73 
74  for (int ix = 0; ix < iw; ++ix)
75  {
76  // do we have to do anything?
77  if (*iptr != T())
78  {
79  //initialize pointers and width
80  int rXstart = ix - origin.x();
81  int rXend = rXstart + sw;
82  int sXstart = 0;
83  if (rXstart < 0)
84  {
85  sXstart -= rXstart;
86  rXstart = 0;
87  }
88  if (rXend > iw) rXend = iw;
89 
90  rptr1 = result.begin() + rYstart * iw + rXstart;
91  sptr1 = se.begin() + sYstart * sw + sXstart;
92 
93  for (int ry = rYstart; ry < rYend; ++ry)
94  {
95  rptr2 = rptr1; sptr2 = sptr1;
96  for (int rx = rXstart; rx < rXend; ++rx)
97  {
98  *rptr2 = std::max(*rptr2,*sptr2);
99  ++rptr2; ++sptr2;
100  }
101  rptr1 += iw; sptr1 += sw;
102  }
103  } // end: we have to do something
104  ++iptr;
105  } // end: for ix
106  } // end: for iy
107  return result;
108 }
109 
110 // ######################################################################
111 template <class PixType>
112 Image<PixType> dilate(Image<PixType> const& img, int seSize, Point2D<int> origin)
113 {
114  return dilate(img, morphologyKernel<typename nrt::pixel_traits<PixType>::pod_type>(seSize, false), origin);
115 }
116 
117 // ######################################################################
118 template <class T>
119 Image<T> erode(Image<T> const& img, Image<T> const& se, Point2D<int> origin)
120 {
121  int const iw = img.width(); int const ih = img.height();
122  int const sw = se.width(); int const sh = se.height();
123 
124  if (origin == Point2D<int>(-1,-1))
125  {
126  origin.x() = (sw - 1) / 2;
127  origin.y() = (sh - 1) / 2;
128  }
129 
130  Image<T> result(iw, ih, ImageInitPolicy::Zeros);
131 
132  typename Image<T>::const_iterator iptr1, iptr2, sptr1, sptr2;
133  typename Image<T>::iterator rptr = result.begin();
134  T se_orig_val = se.at(origin);
135 
136  //loop over result X
137  for (int ry = 0; ry < ih; ++ry)
138  {
139  // initialize height
140  int iYstart = ry - origin.y();
141  int iYend = iYstart + sh;
142  int sYstart = 0;
143  if (iYstart < 0)
144  {
145  sYstart -= iYstart;
146  iYstart = 0;
147  }
148  if (iYend > ih) iYend = ih;
149 
150 
151  // loop over result Y
152  for (int rx = 0; rx < iw; ++rx)
153  {
154  int iXstart = rx - origin.x();
155  int iXend = iXstart + sw;
156  int sXstart = 0;
157  if (iXstart < 0)
158  {
159  sXstart -= iXstart;
160  iXstart = 0;
161  }
162  if (iXend > iw) iXend = iw;
163 
164  bool flag = true; // reset the flag
165  iptr1 = img.begin() + iYstart * iw + iXstart;
166  sptr1 = se.begin() + sYstart * sw + sXstart;
167 
168  //loop over the image covered by the structuring element
169  for (int iy = iYstart; iy < iYend; ++iy)
170  {
171  iptr2 = iptr1; sptr2 = sptr1;
172  for (int ix = iXstart; ix < iXend; ++ ix)
173  {
174  if ((sptr2->val() != 0) && (iptr2->val() == 0))
175  {
176  flag = false;
177  break;
178  } // end: if (*iptr2 == 0)
179  ++iptr2; ++sptr2;
180  } // end: for ix
181 
182  if (!flag) break;
183  iptr1 += iw; sptr1 += sw;
184 
185  } // end: for iy
186 
187  // should we set the pixel?
188  if (flag) *rptr = std::max(*rptr, se_orig_val);
189 
190  ++rptr;
191 
192  } // end: for rx
193  } // end: for ry
194  return result;
195 }
196 
197 // ######################################################################
198 template <class PixType>
199 Image<PixType> erode(Image<PixType> const& img, int seSize, Point2D<int> origin)
200 {
201  return erode(img, morphologyKernel<typename nrt::pixel_traits<PixType>::pod_type>(seSize, false), origin);
202 }
203 
204 // ######################################################################
205 template <class T>
206 Image<T> open(const Image<T>& img, const Image<T>& se, Point2D<int> origin)
207 {
208  return dilate(erode(img,se,origin),se,origin);
209 }
210 
211 // ######################################################################
212 template <class PixType>
213 Image<PixType> open(Image<PixType> const& img, int seSize, Point2D<int> origin)
214 {
215  return open(img, morphologyKernel<typename nrt::pixel_traits<PixType>::pod_type>(seSize, false), origin);
216 }
217 
218 // ######################################################################
219 template <class T>
220 Image<T> close(const Image<T>& img, const Image<T>& se, Point2D<int> origin)
221 {
222  return erode(dilate(img,se,origin),se,origin);
223 }
224 
225 // ######################################################################
226 template <class PixType>
227 Image<PixType> close(Image<PixType> const& img, int seSize, Point2D<int> origin)
228 {
229  return close(img, morphologyKernel<typename nrt::pixel_traits<PixType>::pod_type>(seSize, false), origin);
230 }
231 
232 } // namespace nrt
233 
234 #endif // INCLUDE_NRT_IMAGEPROC_FILTERING_DETAILS_MORPHOLOGYIMPL_H
235