ImageSequence.hh
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_ImageSequence_HH
21 #define MIRTK_ImageSequence_HH
22 
23 #include "mirtk/ImageSequence.h"
24 #include "mirtk/Stream.h"
25 
26 
27 namespace mirtk {
28 
29 
30 ////////////////////////////////////////////////////////////////////////////////
31 // Inline definitions of ImageChannel
32 ////////////////////////////////////////////////////////////////////////////////
33 
34 // -----------------------------------------------------------------------------
35 template <>
36 ImageChannel<irtkBaseImage>::ImageChannel(ImageType *image, bool manage, bool copy)
37 :
38  _Image (image),
39  _Manage(manage)
40 {
41  if (image) {
42  if (image->GetT() > 0) {
43  cerr << "ImageChannel::ImageChannel: Channel image cannot have fourth dimension" << endl;
44  exit(1);
45  }
46  if (copy && !manage) {
47  _Image = BaseImage::New(image);
48  _Manage = true;
49  }
50  }
51 }
52 
53 // -----------------------------------------------------------------------------
54 template <class TImage>
55 ImageChannel<TImage>::ImageChannel(ImageType *image, bool manage, bool copy)
56 :
57  _Image (image),
58  _Manage(manage)
59 {
60  if (image) {
61  if (image->GetT() > 0) {
62  cerr << "ImageChannel::ImageChannel: Channel image cannot have fourth dimension" << endl;
63  exit(1);
64  }
65  if (copy && !manage) {
66  _Image = new ImageType(image);
67  _Manage = true;
68  }
69  }
70 }
71 
72 // -----------------------------------------------------------------------------
73 template <class TImage>
75 {
76  if (_Manage) delete _Image;
77  _Image = other._Image;
78  _Manage = other._Manage;
79  other._Manage = false; // take over ownership
80  return *this;
81 }
82 
83 // -----------------------------------------------------------------------------
84 template <class TImage>
86 :
87  Object(other),
88  _Image (NULL),
89  _Manage(false)
90 {
91  *this = other;
92 }
93 
94 // -----------------------------------------------------------------------------
95 template <> template <class TOtherImage>
97 {
98  if (_Manage) delete _Image;
99  _Image = other._Image;
100  _Manage = other._Manage;
101  other._Manage = false; // take over ownership
102  return *this;
103 }
104 
105 // -----------------------------------------------------------------------------
106 template <> template <class TOtherImage>
108 :
109  Object(other),
110  _Image (NULL),
111  _Manage(false)
112 {
113  *this = other;
114 }
115 
116 // -----------------------------------------------------------------------------
117 template <class TImage>
119 {
120  if (_Manage) delete _Image;
121 }
122 
123 // -----------------------------------------------------------------------------
124 template <>
125 void ImageChannel<irtkBaseImage>::Image(ImageType *image, bool manage, bool copy)
126 {
127  if (_Manage) delete _Image;
128  if (image && copy && !manage) {
129  _Image = BaseImage::New(image);
130  _Manage = true;
131  } else {
132  _Image = image;
133  _Manage = manage;
134  }
135 }
136 
137 // -----------------------------------------------------------------------------
138 template <class TImage>
139 void ImageChannel<TImage>::Image(ImageType *image, bool manage, bool copy)
140 {
141  if (_Manage) delete _Image;
142  if (image && copy && !manage) {
143  _Image = new ImageType(*image);
144  _Manage = true;
145  } else {
146  _Image = image;
147  _Manage = manage;
148  }
149 }
150 
151 // -----------------------------------------------------------------------------
152 template <class TImage>
154 {
155  return _Image;
156 }
157 
158 ////////////////////////////////////////////////////////////////////////////////
159 // Inline definitions of ImageFrame
160 ////////////////////////////////////////////////////////////////////////////////
161 
162 // =============================================================================
163 // Construction/Destruction
164 // =============================================================================
165 
166 // -----------------------------------------------------------------------------
167 template <class TChannel>
169 {
170 }
171 
172 // -----------------------------------------------------------------------------
173 template <class TChannel>
175 {
176 }
177 
178 // =============================================================================
179 // Frame
180 // =============================================================================
181 
182 // -----------------------------------------------------------------------------
183 template <class TChannel>
184 inline void ImageFrame<TChannel>::Add(ImageType *image, bool manage, bool copy)
185 {
186  if (_Channel.size() > 0) {
187  ImageAttributes attr = image->Attributes();
188  attr._t = 1; // may differ
189  attr._dt = _Channel[0].Image().GetTSize();
190  if (attr != _Channel[0].Image().Attributes()) {
191  cerr << "ImageFrame::Add: Attributes of image do not match those of first channel" << endl;
192  exit(1);
193  }
194  }
195  const int T = image->GetT();
196  if (T > 0) {
197  for (int t = 0; t < T; ++t) {
198  BaseImage *channel;
199  image.GetFrame(t, channel);
200  _Channel.push_back(ChannelType(channel, true, false));
201  }
202  } else {
203  _Channel.push_back(ChannelType(image, manage, copy));
204  }
205 }
206 
207 // -----------------------------------------------------------------------------
208 template <class TChannel>
210 {
211  _Channel.clear();
212 }
213 
214 // =============================================================================
215 // Channels
216 // =============================================================================
217 
218 // -----------------------------------------------------------------------------
219 template <class TChannel>
221 {
222  _Channel.resize(n);
223 }
224 
225 // -----------------------------------------------------------------------------
226 template <class TChannel>
228 {
229  return static_cast<int>(_Channel.size());
230 }
231 
232 // -----------------------------------------------------------------------------
233 template <class TChannel>
235 {
236  return _Channel[idx];
237 }
238 
239 // -----------------------------------------------------------------------------
240 template <class TChannel>
242 {
243  return _Channel[idx];
244 }
245 
246 // -----------------------------------------------------------------------------
247 template <class TChannel>
248 inline void ImageFrame<TChannel>::Image(int idx, ImageType *image, bool manage, bool copy)
249 {
250  _Channel[idx].Image(image, manage, copy);
251 }
252 
253 // -----------------------------------------------------------------------------
254 template <class TChannel>
256 {
257  return _Channel[idx].Image();
258 }
259 
260 // =============================================================================
261 // Attributes
262 // =============================================================================
263 
264 // -----------------------------------------------------------------------------
265 template <class TChannel>
267 {
268  const ImageType *image = Image(0);
269  return image ? image->GetImageAttributes() : ImageAttributes();
270 }
271 
272 // -----------------------------------------------------------------------------
273 template <class TChannel>
275 {
276  const ImageType *image = Image(0);
277  return image ? image->GetNumberOfVoxels() : 0;
278 }
279 
280 // -----------------------------------------------------------------------------
281 template <class TChannel>
282 inline int ImageFrame<TChannel>::X() const
283 {
284  const ImageType *image = Image(0);
285  return image ? image->GetX() : 0;
286 }
287 
288 // -----------------------------------------------------------------------------
289 template <class TChannel>
290 inline int ImageFrame<TChannel>::Y() const
291 {
292  const ImageType *image = Image(0);
293  return image ? image->GetY() : 0;
294 }
295 
296 // -----------------------------------------------------------------------------
297 template <class TChannel>
298 inline int ImageFrame<TChannel>::Z() const
299 {
300  const ImageType *image = Image(0);
301  return image ? image->GetZ() : 0;
302 }
303 
304 // -----------------------------------------------------------------------------
305 template <class TChannel>
306 inline double ImageFrame<TChannel>::XSize() const
307 {
308  const ImageType *image = Image(0);
309  return image ? image->GetXSize() : .0;
310 }
311 
312 // -----------------------------------------------------------------------------
313 template <class TChannel>
314 inline double ImageFrame<TChannel>::YSize() const
315 {
316  const ImageType *image = Image(0);
317  return image ? image->GetYSize() : .0;
318 }
319 
320 // -----------------------------------------------------------------------------
321 template <class TChannel>
322 inline double ImageFrame<TChannel>::ZSize() const
323 {
324  const ImageType *image = Image(0);
325  return image ? image->GetZSize() : .0;
326 }
327 
328 // -----------------------------------------------------------------------------
329 template <class TChannel>
330 inline void ImageFrame<TChannel>::GetPixelSize(double *dx, double *dy, double *dz) const
331 {
332  const ImageType *image = Image(0);
333  if (image) image->GetPixelSize(dx, dy, dz);
334  else {
335  if (dx) *dx = .0;
336  if (dy) *dy = .0;
337  if (dz) *dz = .0;
338  }
339 }
340 
341 // -----------------------------------------------------------------------------
342 template <class TChannel>
343 inline void ImageFrame<TChannel>::ImageToWorld(double &x, double &y, double &z) const
344 {
345  const ImageType *image = Image(0);
346  if (image) image->ImageToWorld(x, y, z);
347 }
348 
349 // -----------------------------------------------------------------------------
350 template <class TChannel>
351 inline void ImageFrame<TChannel>::WorldToImage(double &x, double &y, double &z) const
352 {
353  const ImageType *image = Image(0);
354  if (image) image->WorldToImage(x, y, z);
355 }
356 
357 // -----------------------------------------------------------------------------
358 template <class TChannel>
359 inline double ImageFrame<TChannel>::Time() const
360 {
361  const ImageType *image = Image(0);
362  if (image) image->ImageToTime(.0);
363 }
364 
365 ////////////////////////////////////////////////////////////////////////////////
366 // Inline definitions of ImageSequence
367 ////////////////////////////////////////////////////////////////////////////////
368 
369 // =============================================================================
370 // Construction/Destruction
371 // =============================================================================
372 
373 // -----------------------------------------------------------------------------
374 template <class TFrame>
376 {
377 }
378 
379 // -----------------------------------------------------------------------------
380 template <class TFrame>
382 :
383  Object(other),
384  _Frame(other._Frame)
385 {
386 }
387 
388 // -----------------------------------------------------------------------------
389 template <class TFrame>
391 {
392  _Frame = other._Frame;
393  return *this;
394 }
395 
396 // -----------------------------------------------------------------------------
397 template <class TFrame>
399 {
400 }
401 
402 // =============================================================================
403 // Sequence
404 // =============================================================================
405 
406 // -----------------------------------------------------------------------------
407 template <class TFrame>
408 inline void ImageSequence<TFrame>::Add(ImageType *image, bool manage, bool copy)
409 {
410  if (NumberOfFrames() > 0 && NumberOfChannels() > 0) {
411  if (!image->HasSpatialAttributesOf(Image(0, 0))) {
412  cerr << "ImageSequence::Add: Spatial attributes of image differ from those of first frame" << endl;
413  exit(1);
414  }
415  }
416  // Reserve enough entries in vector to ensure that no reallocation
417  // takes place during the insert to keep tmp iterator below valid
418  _Frame.reserve(_Frame.size() + image->GetT());
419  // Insert each input frame (dt != 0) or channel (dt == 0)
420  // Frames are sorted by increasing time and channels appended
421  for (int l = 0; l < image->GetT(); ++l) {
422  // Find corresponding frame or add new one if necessary
423  const double time = image->ImageToTime(l);
424  typename Array<FrameType>::iterator frame = _Frame.begin();
425  while (frame != _Frame.end()) {
426  const double t = frame->Time();
427  if (t == time) break;
428  else if (t > time) {
429  typename Array<FrameType>::iterator tmp = frame - 1;
430  _Frame.insert(frame, FrameType());
431  frame = ++tmp;
432  break;
433  }
434  ++frame;
435  }
436  if (frame == _Frame.end()) {
437  _Frame.push_back(FrameType());
438  frame = _Frame.end() - 1;
439  }
440  // Add channel to frame
441  if (image->GetT() > 0) {
442  BaseImage *channel;
443  image->GetFrame(l, channel);
444  frame->Add(channel, true, false);
445  } else {
446  frame->Add(image, manage, copy);
447  }
448  }
449 }
450 
451 // -----------------------------------------------------------------------------
452 template <class TFrame>
454 {
455  _Frame.clear();
456 }
457 
458 // =============================================================================
459 // Frames
460 // =============================================================================
461 
462 // -----------------------------------------------------------------------------
463 template <class TFrame>
465 {
466  _Frame.resize(n);
467 }
468 
469 // -----------------------------------------------------------------------------
470 template <class TFrame>
472 {
473  return static_cast<int>(_Frame.size());
474 }
475 
476 // -----------------------------------------------------------------------------
477 template <class TFrame>
479 {
480  return _Frame[f];
481 }
482 
483 // -----------------------------------------------------------------------------
484 template <class TFrame>
486 {
487  return _Frame[f];
488 }
489 
490 // =============================================================================
491 // Channels
492 // =============================================================================
493 
494 // -----------------------------------------------------------------------------
495 template <class TFrame>
497 {
498  for (int f = 0; f < NumberOfChannels(); ++f) Frame(f).NumberOfChannels(n);
499 }
500 
501 // -----------------------------------------------------------------------------
502 template <class TFrame>
504 {
505  return NumberOfFrames() > 0 ? Frame(0).NumberOfChannels() : 0;
506 }
507 
508 // -----------------------------------------------------------------------------
509 template <class TFrame>
511 {
512  const int num = NumberOfChannels();
513  return _Frame[idx / num][idx % num];
514 }
515 
516 // -----------------------------------------------------------------------------
517 template <class TFrame>
519 {
520  const int num = NumberOfChannels();
521  return _Frame[idx / num][idx % num];
522 }
523 
524 // -----------------------------------------------------------------------------
525 template <class TFrame>
527 {
528  return _Frame[f][c];
529 }
530 
531 // -----------------------------------------------------------------------------
532 template <class TFrame>
533 inline const typename ImageSequence<TFrame>::ChannelType &ImageSequence<TFrame>::Channel(int f, int c) const
534 {
535  return _Frame[f][c];
536 }
537 
538 // =============================================================================
539 // Images
540 // =============================================================================
541 
542 // -----------------------------------------------------------------------------
543 template <class TFrame>
545 {
546  return NumberOfFrames() * NumberOfChannels();
547 }
548 
549 // -----------------------------------------------------------------------------
550 template <class TFrame>
552 {
553  return Channel(idx).Image();
554 }
555 
556 // -----------------------------------------------------------------------------
557 template <class TFrame>
559 {
560  return Channel(f, c).Image();
561 }
562 
563 // =============================================================================
564 // Attributes
565 // =============================================================================
566 
567 // -----------------------------------------------------------------------------
568 template <class TFrame>
570 {
571  const ImageType *image = Image(0, 0);
572  ImageAttributes attr;
573  if (image) attr = image->GetImageAttributes();
574  attr._t = NumberOfFrames();
575  return attr;
576 }
577 
578 // -----------------------------------------------------------------------------
579 template <class TFrame>
581 {
582  const ImageType *image = Image(0, 0);
583  return image ? image->NumberOfVoxels() : 0;
584 }
585 
586 // -----------------------------------------------------------------------------
587 template <class TFrame>
588 inline int ImageSequence<TFrame>::X() const
589 {
590  const ImageType *image = Image(0, 0);
591  return image ? image->GetX() : 0;
592 }
593 
594 // -----------------------------------------------------------------------------
595 template <class TFrame>
596 inline int ImageSequence<TFrame>::Y() const
597 {
598  const ImageType *image = Image(0, 0);
599  return image ? image->GetY() : 0;
600 }
601 
602 // -----------------------------------------------------------------------------
603 template <class TFrame>
604 inline int ImageSequence<TFrame>::Z() const
605 {
606  const ImageType *image = Image(0, 0);
607  return image ? image->GetZ() : 0;
608 }
609 
610 // -----------------------------------------------------------------------------
611 template <class TFrame>
612 inline int ImageSequence<TFrame>::T() const
613 {
614  return NumberOfFrames();
615 }
616 
617 // -----------------------------------------------------------------------------
618 template <class TFrame>
619 inline double ImageSequence<TFrame>::XSize() const
620 {
621  const ImageType *image = Image(0, 0);
622  return image ? image->GetXSize() : .0;
623 }
624 
625 // -----------------------------------------------------------------------------
626 template <class TFrame>
627 inline double ImageSequence<TFrame>::YSize() const
628 {
629  const ImageType *image = Image(0, 0);
630  return image ? image->GetYSize() : .0;
631 }
632 
633 // -----------------------------------------------------------------------------
634 template <class TFrame>
635 inline double ImageSequence<TFrame>::ZSize() const
636 {
637  const ImageType *image = Image(0, 0);
638  return image ? image->GetZSize() : .0;
639 }
640 
641 // -----------------------------------------------------------------------------
642 template <class TFrame>
643 inline void ImageSequence<TFrame>::GetPixelSize(double *dx, double *dy, double *dz) const
644 {
645  const ImageType *image = Image(0, 0);
646  if (image) image->GetPixelSize(dx, dy, dz);
647  else {
648  if (dx) *dx = .0;
649  if (dy) *dy = .0;
650  if (dz) *dz = .0;
651  }
652 }
653 
654 // -----------------------------------------------------------------------------
655 template <class TFrame>
656 inline void ImageSequence<TFrame>::ImageToWorld(double &x, double &y, double &z) const
657 {
658  const ImageType *image = Image(0, 0);
659  if (image) image->ImageToWorld(x, y, z);
660 }
661 
662 // -----------------------------------------------------------------------------
663 template <class TFrame>
664 inline void ImageSequence<TFrame>::WorldToImage(double &x, double &y, double &z) const
665 {
666  const ImageType *image = Image(0, 0);
667  if (image) image->WorldToImage(x, y, z);
668 }
669 
670 
671 } // namespace mirtk
672 
673 #endif // MIRTK_ImageSequence_HH
~ImageSequence()
Destructor.
double _dt
Voxel t-dimensions (in ms)
double Time() const
Get time of temporal frame.
double YSize() const
Get size of each voxel in y dimension.
int Z() const
Get number of voxels in z dimension for each channel.
TImage ImageType
Type of image associated with this channel.
Definition: ImageSequence.h:51
int NumberOfChannels() const
Get number of channels per frame.
int X() const
Get number of voxels in x dimension for each channel.
static BaseImage * New(const char *)
Read file and construct image.
double YSize() const
Get size of each voxel in y dimension.
int NumberOfChannels() const
Get number of image channels.
void Image(int idx, ImageType *image, bool manage=false, bool copy=false)
TChannel::ImageType ImageType
Type of channel image.
void Clear()
Clear image sequence.
void WorldToImage(double &, double &, double &) const
Convert world to voxel coordinate.
double XSize() const
Get size of each voxel in x dimension.
int Y() const
Get number of voxels in y dimension for each channel.
int Y() const
Get number of voxels in y dimension for each channel.
void Add(ImageType *image, bool manage=false, bool copy=false)
ImageType * _Image
Image associated with this channel.
TFrame::ImageType ImageType
Type of images.
void WorldToImage(double &, double &, double &) const
Convert world to voxel coordinate.
void GetPixelSize(double *, double *, double *) const
Get voxel size.
void ImageToWorld(double &, double &, double &) const
Convert voxel to world coordinate.
TFrame FrameType
Type of frames.
Definition: IOConfig.h:41
void Image(int f, int c, ImageType *image, bool manage, bool copy)
TChannel ChannelType
Type of a channel.
virtual ~ImageChannel()
Destructor.
int _t
Image t-dimension (in voxels)
virtual void GetFrame(BaseImage *&, int, int=-1) const =0
Get time instance (i.e., frame) or channel of image.
int T() const
Get number of frames.
double ZSize() const
Get size of each voxel in z dimension.
ChannelType & Channel(int idx)
int NumberOfFrames() const
Get number of frames.
virtual ~ImageFrame()
Destructor.
ImageAttributes Attributes() const
int Z() const
Get number of voxels in z dimension for each channel.
void GetPixelSize(double *, double *, double *) const
Get voxel size.
bool _Manage
Whether to manage the associated image.
ImageFrame()
Default constructor.
int NumberOfVoxels() const
Get number of voxels per channel.
double ZSize() const
Get size of each voxel in z dimension.
ImageAttributes Attributes() const
ImageSequence & operator=(const ImageSequence &)
Assignment operator.
ImageChannel & operator=(const ImageChannel &)
int X() const
Get number of voxels in x dimension for each channel.
void ImageToWorld(double &, double &, double &) const
Convert voxel to world coordinate.
void Add(ImageType *image, bool manage=false, bool copy=false)
ImageSequence()
Constructor.
FrameType & Frame(int)
Get frame of sequence.
double XSize() const
Get size of each voxel in x dimension.
void Clear()
Clear frame.
ChannelType & Channel(int=0)
Get image channel.
int NumberOfVoxels() const
Get number of voxels per channel.
ImageType * Image() const
Get image associated with this channel.
TFrame::ChannelType ChannelType
Type of channels.
int NumberOfImages() const
Get number of frames times number of channels.