DGtal  1.5.beta
ImageContainerByITKImage.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 ImageContainerByITKImage.ih
19  * @author David Coeurjolly (\c david.coeurjolly@liris.cnrs.fr )
20  * @author Pierre Gueth (\c pierre.gueth@liris.cnrs.fr )
21  * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
22  *
23  * @date 2013/10/23
24  *
25  * Implementation of inline methods defined in ImageContainerByITKImage.h
26  *
27  * This file is part of the DGtal library.
28  */
29 
30 
31 //////////////////////////////////////////////////////////////////////////////
32 #include <cstdlib>
33 //////////////////////////////////////////////////////////////////////////////
34 
35 ///////////////////////////////////////////////////////////////////////////////
36 // IMPLEMENTATION of inline methods.
37 ///////////////////////////////////////////////////////////////////////////////
38 
39 ///////////////////////////////////////////////////////////////////////////////
40 // ----------------------- Standard services ------------------------------
41 
42 namespace DGtal
43 {
44  template<typename TDomain, typename TValue>
45  ImageContainerByITKImage<TDomain, TValue>::~ImageContainerByITKImage()
46  {
47  }
48 
49  template <typename TDomain, typename TValue>
50  ImageContainerByITKImage<TDomain, TValue>::ImageContainerByITKImage(const ImageContainerByITKImage& other)
51  : myITKImagePointer(ITKImage::New()), myDomain()
52  {
53  myITKImagePointer = other.getITKImagePointer();
54  updateDomain();
55  }
56 
57  template <typename TDomain, typename TValue>
58  ImageContainerByITKImage<TDomain, TValue>::ImageContainerByITKImage(const TDomain& aDomain)
59  : myITKImagePointer(ITKImage::New()), myDomain(aDomain)
60  {
61  typename ITKImage::IndexType start;
62  typename ITKImage::SizeType size;
63 
64  const Point lowerBound = aDomain.lowerBound();
65  const Point upperBound = aDomain.upperBound();
66  const Point dec = upperBound-lowerBound;
67 
68  for (Dimension k = 0; k < dimension; k++)
69  {
70  start[k] = lowerBound[k];
71  size[k] = dec[k]+1;
72  }
73 
74  const typename ITKImage::RegionType region(start,size);
75 
76  myITKImagePointer->SetRegions(region);
77  myITKImagePointer->Allocate();
78  myITKImagePointer->FillBuffer(0);
79  }
80 
81  template <typename TDomain, typename TValue>
82  ImageContainerByITKImage<TDomain, TValue>::ImageContainerByITKImage(const ITKImagePointer &aRef)
83  : myITKImagePointer(aRef)
84  {
85  updateDomain();
86  }
87 
88  ///////////////////////////////////////////////////////////////////////////////
89  // Interface - public :
90 
91  template <typename TDomain, typename TValue>
92  void
93  ImageContainerByITKImage<TDomain, TValue>::updateDomain(const Point & inputDomainShift)
94  {
95  myDomainShift = inputDomainShift;
96  const typename ITKImage::RegionType region = myITKImagePointer->GetLargestPossibleRegion();
97  const typename ITKImage::IndexType start = region.GetIndex();
98  const typename ITKImage::SizeType size = region.GetSize();
99 
100  Point lowerBound;
101  Point upperBound;
102  for (Dimension k = 0; k < dimension; k++)
103  {
104  lowerBound[k] = static_cast<typename Point::Component>(start[k]+myDomainShift[k]);
105  upperBound[k] = static_cast<typename Point::Component>(start[k]+size[k]+myDomainShift[k]-1);
106  }
107 
108  myDomain = TDomain(lowerBound, upperBound);
109  }
110 
111  /**
112  * Get the value of an image at a given position.
113  *
114  * @param aPoint position in the image.
115  * @return the value at aPoint.
116  */
117  template <typename TDomain, typename TValue>
118  inline
119  TValue
120  ImageContainerByITKImage<TDomain, TValue>::operator()(const Point &domainPoint) const
121  {
122  return myITKImagePointer->GetPixel(getItkIndexFromDomainPoint(domainPoint));
123  }
124 
125  /**
126  * Get the value of an image at a given position.
127  *
128  * @param aPoint position in the image.
129  * @return the value at aPoint.
130  */
131  template <typename TDomain, typename TValue>
132  inline
133  TValue
134  ImageContainerByITKImage<TDomain, TValue>::operator()(const ConstIterator &it) const
135  {
136  return it.Get();
137  }
138 
139  /**
140  * Get the value of an image at a given position.
141  *
142  * @param aPoint position in the image.
143  * @return the value at aPoint.
144  */
145  template <typename TDomain, typename TValue>
146  inline
147  TValue
148  ImageContainerByITKImage<TDomain, TValue>::operator()(const Iterator &it) const
149  {
150  return it.Get();
151  }
152 
153  template <typename TDomain, typename TValue>
154  inline
155  DGtal::ImageContainerByITKImage<TDomain,TValue>&
156  DGtal::ImageContainerByITKImage<TDomain,TValue>
157  ::operator=(const ImageContainerByITKImage& other)
158  {
159  if (this != &other)
160  {
161  myITKImagePointer = other.myITKImagePointer;
162  updateDomain();
163  }
164  return *this;
165  }
166 
167  template <typename Domain, typename T>
168  inline
169  void
170  ImageContainerByITKImage<Domain, T>::setValue(const Point &domainPoint, const T &V)
171  {
172  myITKImagePointer->SetPixel(getItkIndexFromDomainPoint(domainPoint), V);
173  }
174 
175  template <typename Domain, typename T>
176  inline
177  void
178  ImageContainerByITKImage<Domain, T>::setValue(Iterator &it, const T &V)
179  {
180  it.Set(V);
181  }
182 
183  /**
184  * Writes/Displays the object on an output stream.
185  * @param out the output stream where the object is written.
186  */
187  template<typename TDomain, typename TValue>
188  inline
189  void
190  ImageContainerByITKImage<TDomain, TValue>::selfDisplay ( std::ostream & out ) const
191  {
192  typename ITKImage::RegionType region = myITKImagePointer->GetLargestPossibleRegion();
193 
194  out << "[ImageContainerByITKImage] valuetype=" << sizeof(TValue) << "bytes "
195  << "domain=" << this->domain() << " "
196  << "domainShift=" << this->getDomainShift() << " "
197  << "refcount=" << myITKImagePointer->GetReferenceCount() << " "
198  << "region=" << region.GetIndex() << "/" << region.GetSize();
199  }
200 
201  // ----------------- DomainPoint to/from IndexPoint interface -------------
202  template<typename TDomain, typename TValue>
203  inline
204  typename ImageContainerByITKImage<TDomain, TValue>::Point
205  ImageContainerByITKImage<TDomain, TValue>::getDomainPointFromIndex ( const Point & indexPoint ) const
206  {
207  return indexPoint + myDomainShift;
208  }
209 
210  template<typename TDomain, typename TValue>
211  inline
212  typename ImageContainerByITKImage<TDomain, TValue>::Point
213  ImageContainerByITKImage<TDomain, TValue>::getIndexFromDomainPoint ( const Point & domainPoint ) const
214  {
215  return domainPoint - myDomainShift;
216  }
217 
218  template<typename TDomain, typename TValue>
219  inline
220  typename ImageContainerByITKImage<TDomain, TValue>::Point
221  ImageContainerByITKImage<TDomain, TValue>::getDomainPointFromItkIndex (
222  const typename ITKImage::IndexType &itkIndexPoint) const
223  {
224  Point dgtal_domain_point;
225  for (Dimension k = 0; k < dimension; k++)
226  dgtal_domain_point[k] = itkIndexPoint[k] + myDomainShift[k];
227 
228  return dgtal_domain_point;
229  }
230 
231 
232  template<typename TDomain, typename TValue>
233  inline
234  typename ImageContainerByITKImage<TDomain, TValue>::ITKImage::IndexType
235  ImageContainerByITKImage<TDomain, TValue>::getItkIndexFromDomainPoint(
236  const Point &domainPoint) const
237  {
238  typename ITKImage::IndexType itk_index;
239  for (Dimension k = 0; k < dimension; k++)
240  itk_index[k] = domainPoint[k] - myDomainShift[k];
241 
242  return itk_index;
243  }
244 
245  // ------------------------- PhysicalPoint interface ----------------------
246  template<typename TDomain, typename TValue>
247  inline
248  typename ImageContainerByITKImage<TDomain, TValue>::PhysicalPoint
249  ImageContainerByITKImage<TDomain, TValue>::getPhysicalPointFromDomainPoint(const Point &domainPoint) const
250  {
251  // Transform input Point to itk Index.
252  // The index would be different than the domain point if myDomainShift is not zero.
253  const auto itk_index = getItkIndexFromDomainPoint(domainPoint);
254  // ITK performs the transform between index and physical spaces.
255  typename ITKImage::PointType itk_point;
256  myITKImagePointer->template TransformIndexToPhysicalPoint<typename RealPoint::Component>(itk_index, itk_point);
257 
258  // Transform itk physical point to dgtal
259  PhysicalPoint dgtal_real_point;
260  for (Dimension k = 0; k < dimension; k++)
261  dgtal_real_point[k] = itk_point[k];
262 
263  return dgtal_real_point;
264  }
265 
266  template<typename TDomain, typename TValue>
267  inline
268  typename ImageContainerByITKImage<TDomain, TValue>::Point
269  ImageContainerByITKImage<TDomain, TValue>::getDomainPointFromPhysicalPoint(const PhysicalPoint &physicalPoint) const
270  {
271  // Transform input dgtal point to itk point (real points)
272  typename ITKImage::PointType itk_point;
273  for (Dimension k = 0; k < dimension; k++)
274  itk_point[k] = physicalPoint[k];
275 
276  // ITK performs the transform between index and physical spaces.
277  typename ITKImage::IndexType itk_index;
278  myITKImagePointer->TransformPhysicalPointToIndex(itk_point, itk_index);
279 
280  return getDomainPointFromItkIndex(itk_index);
281  }
282 
283  template<typename TDomain, typename TValue>
284  inline
285  typename ImageContainerByITKImage<TDomain, TValue>::PhysicalPoint
286  ImageContainerByITKImage<TDomain, TValue>::getLowerBoundAsPhysicalPoint() const
287  {
288  return getPhysicalPointFromDomainPoint(myDomain.lowerBound());
289  }
290 
291  template<typename TDomain, typename TValue>
292  inline
293  typename ImageContainerByITKImage<TDomain, TValue>::PhysicalPoint
294  ImageContainerByITKImage<TDomain, TValue>::getUpperBoundAsPhysicalPoint() const
295  {
296  return getPhysicalPointFromDomainPoint(myDomain.upperBound());
297  }
298 
299  template<typename TDomain, typename TValue>
300  inline
301  typename ImageContainerByITKImage<TDomain, TValue>::ImageSpacing
302  ImageContainerByITKImage<TDomain, TValue>::getImageSpacing() const
303  {
304  ImageSpacing r;
305  auto s = myITKImagePointer->GetSpacing();
306  for (Dimension k = 0; k < dimension; k++)
307  r[k] = s[k];
308  return r;
309  }
310  template<typename TDomain, typename TValue>
311  inline
312  void
313  ImageContainerByITKImage<TDomain, TValue>::setImageSpacing(const ImageContainerByITKImage<TDomain, TValue>::ImageSpacing &s) const
314  {
315  ITKSpacingValueType is [dimension];
316  for (Dimension k = 0; k < dimension; k++)
317  is[k] = s[k];
318  myITKImagePointer->SetSpacing(is);
319  }
320 
321  ///////////////////////////////////////////////////////////////////////////////
322  // Implementation of inline functions //
323 
324  template<typename TDomain, typename TValue>
325  inline
326  std::ostream&
327  operator<< ( std::ostream & out,
328  const ImageContainerByITKImage<TDomain, TValue> & object )
329  {
330  object.selfDisplay( out );
331  return out;
332  }
333 }
334 // //
335 ///////////////////////////////////////////////////////////////////////////////
336 
337