DGtal  0.9.2
ImageHelper.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file ImageHelper.ih
19  * @author Tristan Roussillon (\c tristan.roussillon@liris.cnrs.fr )
20  * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
21  *
22  * @date 2012/02/15
23  *
24  * Implementation of inline methods defined in ImageHelper.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 
30 //////////////////////////////////////////////////////////////////////////////
31 #include <cstdlib>
32 #include <vector>
33 #include <iostream>
34 #include "DGtal/kernel/PointVector.h"
35 //////////////////////////////////////////////////////////////////////////////
36 
37 
38 
39 //------------------------------------------------------------------------------
40 template<typename I, typename O, typename P>
41 inline
42 void
43 DGtal::setFromPointsRangeAndPredicate(const I& itb, const I& ite, const O& ito, const P& aPred)
44 {
45  BOOST_CONCEPT_ASSERT(( concepts::CPointPredicate<P> ));
46  BOOST_CONCEPT_ASSERT(( boost::InputIterator<I> ));
47  BOOST_CONCEPT_ASSERT(( boost::OutputIterator<O,typename P::Point> ));
48 
49  functors::NotPointPredicate<P> nPred( aPred );
50  std::remove_copy_if(itb, ite, ito, nPred);
51 }
52 
53 //------------------------------------------------------------------------------
54 template<typename I, typename O, typename F>
55 inline
56 void
57 DGtal::setFromPointsRangeAndFunctor(const I& itb, const I& ite, const O& ito,
58  const F& aFunctor, const typename F::Value& aThreshold)
59 {
60  BOOST_CONCEPT_ASSERT(( concepts::CPointFunctor<F> ));
61  BOOST_CONCEPT_ASSERT(( boost::InputIterator<I> ));
62  BOOST_CONCEPT_ASSERT(( boost::OutputIterator<O,typename F::Point> ));
63 
64  typedef functors::Thresholder<typename F::Value,false,false> T;
65  T t( aThreshold );
66  functors::Composer<F, T, bool> aPred(aFunctor, t);
67  std::remove_copy_if(itb, ite, ito, aPred);
68 }
69 
70 //------------------------------------------------------------------------------
71 template<typename I, typename O>
72 inline
73 void
74 DGtal::setFromImage(const I& aImg, const O& ito, const typename I::Value& aThreshold)
75 {
76  BOOST_CONCEPT_ASSERT(( concepts::CConstImage<I> ));
77 
78  typename I::Domain d = aImg.domain();
79  setFromPointsRangeAndFunctor(d.begin(), d.end(), ito, aImg, aThreshold);
80 }
81 
82 //------------------------------------------------------------------------------
83 template<typename I, typename O>
84 inline
85 void
86 DGtal::setFromImage(const I& aImg, const O& ito,
87  const typename I::Value& low,
88  const typename I::Value& up)
89 {
90  BOOST_CONCEPT_ASSERT(( concepts::CConstImage<I> ));
91  ASSERT( low < up );
92 
93  //domain
94  typename I::Domain d = aImg.domain();
95  //predicate from two thresholders and an image
96  typedef functors::Thresholder<typename I::Value,true,false> T1;
97  T1 t1( low );
98  typedef functors::Thresholder<typename I::Value,false,false> T2;
99  T2 t2( up );
100  typedef functors::PredicateCombiner< T1, T2, functors::OrBoolFct2 > P;
101  P p( t1, t2, functors::OrBoolFct2() );
102  functors::Composer<I, P, bool> aPred(aImg, p);
103  //call
104  std::remove_copy_if(d.begin(), d.end(), ito, aPred);
105 }
106 
107 //------------------------------------------------------------------------------
108 template<typename It, typename Im>
109 inline
110 void
111 DGtal::imageFromRangeAndValue(const It& itb, const It& ite, Im& aImg,
112  const typename Im::Value& aValue)
113 {
114  BOOST_CONCEPT_ASSERT(( boost::InputIterator<It> ));
115  BOOST_CONCEPT_ASSERT(( concepts::CImage<Im> ));
116 
117  typename Im::Domain d = aImg.domain();
118  for (It it = itb; it != ite; ++it)
119  {
120  if (d.isInside( *it ))
121  aImg.setValue( *it, aValue );
122  }
123 }
124 
125 //------------------------------------------------------------------------------
126 template<typename R, typename I>
127 inline
128 void
129 DGtal::imageFromRangeAndValue(const R& aRange, I& aImg,
130  const typename I::Value& aValue)
131 {
132  BOOST_CONCEPT_ASSERT(( concepts::CConstSinglePassRange<R> ));
133  BOOST_CONCEPT_ASSERT(( concepts::CImage<I> ));
134 
135  imageFromRangeAndValue( aRange.begin(), aRange.end(), aImg, aValue);
136 }
137 
138 //------------------------------------------------------------------------------
139 template<typename I, typename F>
140 inline
141 void
142 DGtal::imageFromFunctor(I& aImg, const F& aFun)
143 {
144  BOOST_CONCEPT_ASSERT(( concepts::CImage<I> ));
145  BOOST_CONCEPT_ASSERT(( concepts::CPointFunctor<F> ));
146 
147  typename I::Domain d = aImg.domain();
148 
149  std::transform(d.begin(), d.end(), aImg.range().outputIterator(), aFun );
150 }
151 
152 //------------------------------------------------------------------------------
153 template<typename I1, typename I2>
154 inline
155 void
156 DGtal::imageFromImage(I1& aImg1, const I2& aImg2)
157 {
158  BOOST_CONCEPT_ASSERT(( concepts::CImage<I1> ));
159  BOOST_CONCEPT_ASSERT(( concepts::CConstImage<I2> ));
160 
161  typename I2::ConstRange r = aImg2.constRange();
162  std::copy( r.begin(), r.end(), aImg1.range().outputIterator() );
163 }
164 
165 //------------------------------------------------------------------------------
166 template<typename I, typename S, typename D, typename V>
167 struct InsertAndSetValue
168 {
169  static bool implementation(I& aImg, S& aSet,
170  const typename D::Point& aPoint,
171  const V& aValue)
172  {
173  // std::pair<typename S::Iterator, bool> res
174  // = aSet.insert( aPoint );
175  // aImg.setValue( aPoint, aValue );
176  // return res.second;
177 
178  bool found = true;
179  if ( aSet.find( aPoint ) == aSet.end() )
180  { //if not found
181  found = false;
182  aSet.insert( aPoint );
183  aImg.setValue( aPoint, aValue );
184  }
185  return !found;
186  }
187 };
188 //------------------------------------------------------------------------------
189 //Partial specialization
190 template<typename D, typename V>
191 struct InsertAndSetValue<
192  DGtal::ImageContainerBySTLMap<D,V>,
193  DGtal::DigitalSetFromMap<DGtal::ImageContainerBySTLMap<D,V> >,
194  D, V >
195 {
196  static bool implementation
197  (DGtal::ImageContainerBySTLMap<D,V>& aImg,
198  DGtal::DigitalSetFromMap<DGtal::ImageContainerBySTLMap<D,V> >& /*aSet*/,
199  const typename D::Point& aPoint,
200  const V& aValue)
201  {
202  typedef typename D::Point P;
203  typedef typename DGtal::ImageContainerBySTLMap<D,V>::iterator Iterator;
204 
205  std::pair<P, V>
206  pair( aPoint, aValue );
207  std::pair<Iterator, bool> res
208  = aImg.insert( pair );
209  return res.second;
210  }
211 };
212 
213 //------------------------------------------------------------------------------
214 template<typename I, typename S>
215 inline
216 bool
217 DGtal::insertAndSetValue(I& aImg, S& aSet,
218  const typename I::Point& aPoint,
219  const typename I::Value& aValue )
220 {
221  BOOST_CONCEPT_ASSERT(( concepts::CImage<I> ));
222  BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet<S> ));
223  BOOST_STATIC_ASSERT(( boost::is_same< typename I::Point, typename S::Point >::value ));
224 
225  typedef typename I::Domain D;
226  typedef typename I::Value V;
227  return InsertAndSetValue<I,S,D,V>::implementation(aImg, aSet, aPoint, aValue);
228 }
229 
230 //------------------------------------------------------------------------------
231 template<typename I, typename S, typename D, typename V>
232 struct InsertAndAlwaysSetValue
233 {
234  static bool implementation(I& aImg, S& aSet,
235  const typename D::Point& aPoint,
236  const V& aValue)
237  {
238  bool found = false;
239  if ( aSet.find( aPoint ) != aSet.end() )
240  found = true;
241  //always set value
242  aSet.insert( aPoint );
243  aImg.setValue( aPoint, aValue );
244  return !found;
245  }
246 };
247 //------------------------------------------------------------------------------
248 //Partial specialization
249 template<typename D, typename V>
250 struct InsertAndAlwaysSetValue<
251  DGtal::ImageContainerBySTLMap<D,V>,
252  DGtal::DigitalSetFromMap<DGtal::ImageContainerBySTLMap<D,V> >,
253  D, V >
254 {
255  static bool implementation
256  (DGtal::ImageContainerBySTLMap<D,V>& aImg,
257  DGtal::DigitalSetFromMap<DGtal::ImageContainerBySTLMap<D,V> >& /*aSet*/,
258  const typename D::Point& aPoint,
259  const V& aValue)
260  {
261  typedef typename D::Point P;
262  typedef typename DGtal::ImageContainerBySTLMap<D,V>::iterator Iterator;
263 
264  std::pair<P, V>
265  pair( aPoint, aValue );
266  std::pair<Iterator, bool> res
267  = aImg.insert( pair );
268  bool flag = res.second;
269  if (flag == false) //set value even in this case
270  res.first->second = aValue;
271  return flag;
272  }
273 };
274 
275 //------------------------------------------------------------------------------
276 template<typename I, typename S>
277 inline
278 bool
279 DGtal::insertAndAlwaysSetValue(I& aImg, S& aSet,
280  const typename I::Point& aPoint,
281  const typename I::Value& aValue )
282 {
283 
284  BOOST_CONCEPT_ASSERT(( concepts::CImage<I> ));
285  BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet<S> ));
286  BOOST_STATIC_ASSERT(( boost::is_same< typename I::Point, typename S::Point >::value ));
287 
288  typedef typename I::Domain D;
289  typedef typename I::Value V;
290  return InsertAndAlwaysSetValue<I,S,D,V>::implementation(aImg, aSet, aPoint, aValue);
291 }
292 
293 
294 //------------------------------------------------------------------------------
295 template<typename I, typename S, typename D, typename V>
296 struct FindAndGetValue
297 {
298  static bool implementation(const I& aImg, const S& aSet,
299  const typename D::Point& aPoint,
300  V& aValue)
301  {
302  if ( aSet.find( aPoint ) != aSet.end() )
303  {
304  aValue = aImg( aPoint );
305  return true;
306  }
307  else return false;
308  }
309 };
310 //------------------------------------------------------------------------------
311 //Partial specialization
312 template<typename D, typename V>
313 struct FindAndGetValue<
314  DGtal::ImageContainerBySTLMap<D,V>,
315  DGtal::DigitalSetFromMap<DGtal::ImageContainerBySTLMap<D,V> >,
316  D, V >
317 {
318  static bool implementation
319  (const DGtal::ImageContainerBySTLMap<D,V>& aImg,
320  const DGtal::DigitalSetFromMap<DGtal::ImageContainerBySTLMap<D,V> >& /*aSet*/,
321  const typename D::Point& aPoint,
322  V& aValue)
323  {
324  typedef typename DGtal::ImageContainerBySTLMap<D,V>::const_iterator ConstIterator;
325 
326  ConstIterator it = aImg.find( aPoint );
327  if ( it != aImg.end() )
328  {
329  aValue = it->second;
330  return true;
331  }
332  else return false;
333  }
334 };
335 
336 //------------------------------------------------------------------------------
337 template<typename I, typename S>
338 inline
339 bool
340 DGtal::findAndGetValue(const I& aImg, const S& aSet,
341  const typename I::Point& aPoint,
342  typename I::Value& aValue )
343 {
344 
345  BOOST_CONCEPT_ASSERT(( concepts::CConstImage<I> ));
346  BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet<S> ));
347  BOOST_STATIC_ASSERT(( boost::is_same< typename I::Point, typename S::Point >::value ));
348 
349  typedef typename I::Domain D;
350  typedef typename I::Value V;
351  return FindAndGetValue<I,S,D,V>::implementation(aImg, aSet, aPoint, aValue);
352 }
353 
354 
355 
356 
357 
358 
359 
360