Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkIGTLMessageToUSImageFilter.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 #include <igtlImageMessage.h>
19 #include <itkByteSwapper.h>
20 
23 {
24  m_upstream->Update();
25 
26  mitk::IGTLMessage* msg = m_upstream->GetOutput();
27 
28  if (msg != nullptr && (!msg->IsDataValid() || std::strcmp(msg->GetIGTLMessageType(), "IMAGE") != 0))
29  {
30  img = m_previousImage;
31  return;
32  }
33 
34  igtl::MessageBase::Pointer msgBase = msg->GetMessage();
35  igtl::ImageMessage* imgMsg = (igtl::ImageMessage*)(msgBase.GetPointer());
36 
37  bool big_endian = (imgMsg->GetEndian() == igtl::ImageMessage::ENDIAN_BIG);
38 
39  if (imgMsg->GetCoordinateSystem() != igtl::ImageMessage::COORDINATE_RAS)
40  {
41  // TODO: Which coordinate system does MITK use?
42  mitkThrow() << "Can not handle messages with LPS coordinate system";
43  }
44 
45  switch (imgMsg->GetScalarType())
46  {
47  case igtl::ImageMessage::TYPE_UINT8:
48  Initiate<unsigned char>(img, imgMsg, big_endian);
49  break;
50  case igtl::ImageMessage::TYPE_INT8:
51  Initiate<char>(img, imgMsg, big_endian);
52  break;
53  case igtl::ImageMessage::TYPE_UINT16:
54  Initiate<unsigned short>(img, imgMsg, big_endian);
55  break;
56  case igtl::ImageMessage::TYPE_INT16:
57  Initiate<short>(img, imgMsg, big_endian);
58  break;
59  case igtl::ImageMessage::TYPE_UINT32:
60  Initiate<unsigned int>(img, imgMsg, big_endian);
61  break;
62  case igtl::ImageMessage::TYPE_INT32:
63  Initiate<int>(img, imgMsg, big_endian);
64  break;
65  case igtl::ImageMessage::TYPE_FLOAT32:
66  Initiate<float>(img, imgMsg, big_endian);
67  break;
68  case igtl::ImageMessage::TYPE_FLOAT64:
69  Initiate<double>(img, imgMsg, big_endian);
70  break;
71  default:
72  mitkThrow() << "Incompatible PixelType " << imgMsg;
73  }
74 }
75 
76 template <typename TPixel>
77 void mitk::IGTLMessageToUSImageFilter::Initiate(mitk::Image::Pointer& img,
78  igtl::ImageMessage* msg,
79  bool big_endian)
80 {
81  typedef itk::Image<TPixel, 3> ImageType;
82 
83  typename ImageType::Pointer output = ImageType::New();
84  typename ImageType::RegionType region;
85  typename ImageType::RegionType::SizeType size;
86  typename ImageType::RegionType::IndexType index;
87  typename ImageType::SpacingType spacing;
88  typename ImageType::PointType origin;
89 
90  // Copy dimensions
91  int dims[3];
92  msg->GetDimensions(dims);
93  size_t num_pixel = 1;
94  for (size_t i = 0; i < 3; i++)
95  {
96  size[i] = dims[i];
97  num_pixel *= dims[i];
98  }
99 
100  // Handle subvolume information. We want the subvolume to be the whole image
101  // for now.
102  int sdims[3], offs[3];
103  msg->GetSubVolume(sdims, offs);
104  for (size_t i = 0; i < 3; i++)
105  {
106  if (offs[i] != 0 || sdims[i] != dims[i])
107  {
108  // TODO: Handle messages with smaller subvolume than whole image
109  throw("Can not handle message with smaller subvolume than whole image");
110  }
111  }
112 
113  index.Fill(0);
114 
115  float matF[4][4];
116  msg->GetMatrix(matF);
117  vtkMatrix4x4* vtkMatrix = vtkMatrix4x4::New();
118 
119  for (size_t i = 0; i < 4; ++i)
120  for (size_t j = 0; j < 4; ++j)
121  vtkMatrix->SetElement(i, j, matF[i][j]);
122 
123  float spacingMsg[3];
124 
125  msg->GetSpacing(spacingMsg);
126 
127  for (int i = 0; i < 3; ++i)
128  spacing[i] = spacingMsg[i];
129 
130  region.SetSize(size);
131  region.SetIndex(index);
132  output->SetRegions(region);
133  output->SetSpacing(spacing);
134  output->Allocate();
135 
136  TPixel* in = (TPixel*)msg->GetScalarPointer();
137  TPixel* out = (TPixel*)output->GetBufferPointer();
138  memcpy(out, in, num_pixel * sizeof(TPixel));
139  if (big_endian)
140  {
141  // Even though this method is called "FromSystemToBigEndian", it also swaps
142  // "FromBigEndianToSystem".
143  // This makes sense, but might be confusing at first glance.
144  itk::ByteSwapper<TPixel>::SwapRangeFromSystemToBigEndian(out, num_pixel);
145  }
146  else
147  {
148  itk::ByteSwapper<TPixel>::SwapRangeFromSystemToLittleEndian(out, num_pixel);
149  }
150 
151  img = mitk::Image::New();
152  img->InitializeByItk(output.GetPointer());
153  img->SetVolume(output->GetBufferPointer());
154  //img->GetGeometry()->SetIndexToWorldTransformByVtkMatrix(vtkMatrix);
155  m_previousImage = img;
156  vtkMatrix->Delete();
157 
158  float iorigin[3];
159  msg->GetOrigin(iorigin);
160  for (size_t i = 0; i < 3; i++)
161  {
162  origin[i] = iorigin[i];
163  }
164  output->SetOrigin(origin);
165 }
166 
168  : m_upstream(nullptr)
169 {
170  MITK_DEBUG << "Instantiated this (" << this << ") mitkIGTMessageToUSImageFilter\n";
171 }
172 
174  unsigned int numOutputs)
175 {
176  if (numOutputs > 1)
177  {
178  throw("Can only have 1 output for IGTLMessageToUSImageFilter.");
179  }
180 }
181 
183  mitk::IGTLMessageSource* UpstreamFilter)
184 {
185  MITK_DEBUG << "Connected this (" << this << ") mitkIGTLMessageToUSImageFilter to MessageSource (" << UpstreamFilter << ")\n";
186  m_upstream = UpstreamFilter;
187 }
virtual bool IsDataValid() const
returns true if the object contains valid data
virtual igtl::MessageBase::Pointer GetMessage() const
returns the OpenIGTLink message
void ConnectTo(mitk::IGTLMessageSource *UpstreamFilter)
Connects the input of this filter to the outputs of the given IGTLMessageSource.
mitk::Point3D PointType
itk::SmartPointer< Self > Pointer
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
const char * GetIGTLMessageType() const
map::core::discrete::Elements< 3 >::InternalImageType ImageType
void SetNumberOfExpectedOutputs(unsigned int numOutputs)
Sets the number of expected outputs.
IGTLMessage * GetOutput(void)
return the output (output with id 0) of the filter
A wrapper for the OpenIGTLink message type.
#define mitkThrow()
OpenIGTLink message source.
static Pointer New()
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
Definition: jsoncpp.cpp:244
virtual void GetNextRawImage(mitk::Image::Pointer &img)
Copies the data from the next OIGTL message to an mitk::Image.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.