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 <>
ImageChannel(ImageType * image,bool manage,bool copy)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>
ImageChannel(ImageType * image,bool manage,bool copy)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>
operator =(const ImageChannel<TImage> & other)74 ImageChannel<TImage> &ImageChannel<TImage>::operator =(const ImageChannel<TImage> &other)
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>
ImageChannel(const ImageChannel<TImage> & other)85 ImageChannel<TImage>::ImageChannel(const ImageChannel<TImage> &other)
86 :
87 Object(other),
88 _Image (NULL),
89 _Manage(false)
90 {
91 *this = other;
92 }
93
94 // -----------------------------------------------------------------------------
95 template <> template <class TOtherImage>
operator =(const ImageChannel<TOtherImage> & other)96 ImageChannel<irtkBaseImage> &ImageChannel<irtkBaseImage>::operator =(const ImageChannel<TOtherImage> &other)
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>
ImageChannel(const ImageChannel<TOtherImage> & other)107 ImageChannel<irtkBaseImage>::ImageChannel(const ImageChannel<TOtherImage> &other)
108 :
109 Object(other),
110 _Image (NULL),
111 _Manage(false)
112 {
113 *this = other;
114 }
115
116 // -----------------------------------------------------------------------------
117 template <class TImage>
~ImageChannel()118 ImageChannel<TImage>::~ImageChannel()
119 {
120 if (_Manage) delete _Image;
121 }
122
123 // -----------------------------------------------------------------------------
124 template <>
Image(ImageType * image,bool manage,bool copy)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>
Image(ImageType * image,bool manage,bool copy)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>
Image() const153 TImage *ImageChannel<TImage>::Image() const
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>
ImageFrame()168 inline ImageFrame<TChannel>::ImageFrame()
169 {
170 }
171
172 // -----------------------------------------------------------------------------
173 template <class TChannel>
~ImageFrame()174 inline ImageFrame<TChannel>::~ImageFrame()
175 {
176 }
177
178 // =============================================================================
179 // Frame
180 // =============================================================================
181
182 // -----------------------------------------------------------------------------
183 template <class TChannel>
Add(ImageType * image,bool manage,bool copy)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>
Clear()209 inline void ImageFrame<TChannel>::Clear()
210 {
211 _Channel.clear();
212 }
213
214 // =============================================================================
215 // Channels
216 // =============================================================================
217
218 // -----------------------------------------------------------------------------
219 template <class TChannel>
NumberOfChannels(int n)220 inline void ImageFrame<TChannel>::NumberOfChannels(int n)
221 {
222 _Channel.resize(n);
223 }
224
225 // -----------------------------------------------------------------------------
226 template <class TChannel>
NumberOfChannels() const227 inline int ImageFrame<TChannel>::NumberOfChannels() const
228 {
229 return static_cast<int>(_Channel.size());
230 }
231
232 // -----------------------------------------------------------------------------
233 template <class TChannel>
Channel(int idx)234 inline typename ImageFrame<TChannel>::ChannelType &ImageFrame<TChannel>::Channel(int idx)
235 {
236 return _Channel[idx];
237 }
238
239 // -----------------------------------------------------------------------------
240 template <class TChannel>
Channel(int idx) const241 inline const typename ImageFrame<TChannel>::ChannelType &ImageFrame<TChannel>::Channel(int idx) const
242 {
243 return _Channel[idx];
244 }
245
246 // -----------------------------------------------------------------------------
247 template <class TChannel>
Image(int idx,ImageType * image,bool manage,bool copy)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>
Image(int idx) const255 inline typename ImageFrame<TChannel>::ImageType *ImageFrame<TChannel>::Image(int idx) const
256 {
257 return _Channel[idx].Image();
258 }
259
260 // =============================================================================
261 // Attributes
262 // =============================================================================
263
264 // -----------------------------------------------------------------------------
265 template <class TChannel>
Attributes() const266 inline ImageAttributes ImageFrame<TChannel>::Attributes() const
267 {
268 const ImageType *image = Image(0);
269 return image ? image->GetImageAttributes() : ImageAttributes();
270 }
271
272 // -----------------------------------------------------------------------------
273 template <class TChannel>
NumberOfVoxels() const274 inline int ImageFrame<TChannel>::NumberOfVoxels() const
275 {
276 const ImageType *image = Image(0);
277 return image ? image->GetNumberOfVoxels() : 0;
278 }
279
280 // -----------------------------------------------------------------------------
281 template <class TChannel>
X() const282 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>
Y() const290 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>
Z() const298 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>
XSize() const306 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>
YSize() const314 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>
ZSize() const322 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>
GetPixelSize(double * dx,double * dy,double * dz) const330 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>
ImageToWorld(double & x,double & y,double & z) const343 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>
WorldToImage(double & x,double & y,double & z) const351 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>
Time() const359 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>
ImageSequence()375 inline ImageSequence<TFrame>::ImageSequence()
376 {
377 }
378
379 // -----------------------------------------------------------------------------
380 template <class TFrame>
ImageSequence(const ImageSequence & other)381 inline ImageSequence<TFrame>::ImageSequence(const ImageSequence &other)
382 :
383 Object(other),
384 _Frame(other._Frame)
385 {
386 }
387
388 // -----------------------------------------------------------------------------
389 template <class TFrame>
operator =(const ImageSequence & other)390 inline ImageSequence<TFrame> &ImageSequence<TFrame>::operator =(const ImageSequence &other)
391 {
392 _Frame = other._Frame;
393 return *this;
394 }
395
396 // -----------------------------------------------------------------------------
397 template <class TFrame>
~ImageSequence()398 inline ImageSequence<TFrame>::~ImageSequence()
399 {
400 }
401
402 // =============================================================================
403 // Sequence
404 // =============================================================================
405
406 // -----------------------------------------------------------------------------
407 template <class TFrame>
Add(ImageType * image,bool manage,bool copy)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>
Clear()453 inline void ImageSequence<TFrame>::Clear()
454 {
455 _Frame.clear();
456 }
457
458 // =============================================================================
459 // Frames
460 // =============================================================================
461
462 // -----------------------------------------------------------------------------
463 template <class TFrame>
NumberOfFrames(int n) const464 inline void ImageSequence<TFrame>::NumberOfFrames(int n) const
465 {
466 _Frame.resize(n);
467 }
468
469 // -----------------------------------------------------------------------------
470 template <class TFrame>
NumberOfFrames() const471 inline int ImageSequence<TFrame>::NumberOfFrames() const
472 {
473 return static_cast<int>(_Frame.size());
474 }
475
476 // -----------------------------------------------------------------------------
477 template <class TFrame>
Frame(int f)478 inline typename ImageSequence<TFrame>::FrameType &ImageSequence<TFrame>::Frame(int f)
479 {
480 return _Frame[f];
481 }
482
483 // -----------------------------------------------------------------------------
484 template <class TFrame>
Frame(int f) const485 inline const typename ImageSequence<TFrame>::FrameType &ImageSequence<TFrame>::Frame(int f) const
486 {
487 return _Frame[f];
488 }
489
490 // =============================================================================
491 // Channels
492 // =============================================================================
493
494 // -----------------------------------------------------------------------------
495 template <class TFrame>
NumberOfChannels(int n) const496 inline void ImageSequence<TFrame>::NumberOfChannels(int n) const
497 {
498 for (int f = 0; f < NumberOfChannels(); ++f) Frame(f).NumberOfChannels(n);
499 }
500
501 // -----------------------------------------------------------------------------
502 template <class TFrame>
NumberOfChannels() const503 inline int ImageSequence<TFrame>::NumberOfChannels() const
504 {
505 return NumberOfFrames() > 0 ? Frame(0).NumberOfChannels() : 0;
506 }
507
508 // -----------------------------------------------------------------------------
509 template <class TFrame>
Channel(int idx)510 inline typename ImageSequence<TFrame>::ChannelType &ImageSequence<TFrame>::Channel(int idx)
511 {
512 const int num = NumberOfChannels();
513 return _Frame[idx / num][idx % num];
514 }
515
516 // -----------------------------------------------------------------------------
517 template <class TFrame>
Channel(int idx) const518 inline const typename ImageSequence<TFrame>::ChannelType &ImageSequence<TFrame>::Channel(int idx) const
519 {
520 const int num = NumberOfChannels();
521 return _Frame[idx / num][idx % num];
522 }
523
524 // -----------------------------------------------------------------------------
525 template <class TFrame>
Channel(int f,int c)526 inline typename ImageSequence<TFrame>::ChannelType &ImageSequence<TFrame>::Channel(int f, int c)
527 {
528 return _Frame[f][c];
529 }
530
531 // -----------------------------------------------------------------------------
532 template <class TFrame>
Channel(int f,int c) const533 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>
NumberOfImages() const544 inline int ImageSequence<TFrame>::NumberOfImages() const
545 {
546 return NumberOfFrames() * NumberOfChannels();
547 }
548
549 // -----------------------------------------------------------------------------
550 template <class TFrame>
Image(int idx) const551 inline typename ImageSequence<TFrame>::ImageType *ImageSequence<TFrame>::Image(int idx) const
552 {
553 return Channel(idx).Image();
554 }
555
556 // -----------------------------------------------------------------------------
557 template <class TFrame>
Image(int f,int c) const558 inline typename ImageSequence<TFrame>::ImageType *ImageSequence<TFrame>::Image(int f, int c) const
559 {
560 return Channel(f, c).Image();
561 }
562
563 // =============================================================================
564 // Attributes
565 // =============================================================================
566
567 // -----------------------------------------------------------------------------
568 template <class TFrame>
Attributes() const569 inline ImageAttributes ImageSequence<TFrame>::Attributes() const
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>
NumberOfVoxels() const580 inline int ImageSequence<TFrame>::NumberOfVoxels() const
581 {
582 const ImageType *image = Image(0, 0);
583 return image ? image->NumberOfVoxels() : 0;
584 }
585
586 // -----------------------------------------------------------------------------
587 template <class TFrame>
X() const588 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>
Y() const596 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>
Z() const604 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>
T() const612 inline int ImageSequence<TFrame>::T() const
613 {
614 return NumberOfFrames();
615 }
616
617 // -----------------------------------------------------------------------------
618 template <class TFrame>
XSize() const619 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>
YSize() const627 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>
ZSize() const635 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>
GetPixelSize(double * dx,double * dy,double * dz) const643 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>
ImageToWorld(double & x,double & y,double & z) const656 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>
WorldToImage(double & x,double & y,double & z) const664 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
674