Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkLookupTable.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 
17 #include "mitkLookupTable.h"
18 #include <itkProcessObject.h>
19 
20 #include <vtkColorTransferFunction.h>
21 #include <vtkPiecewiseFunction.h>
22 
23 #include <Colortables/HotIron.h>
24 #include <Colortables/Jet.h>
25 #include <Colortables/PET20.h>
26 #include <Colortables/PETColor.h>
28 
29 const char *const mitk::LookupTable::typenameList[] = {
30  "Grayscale",
31  "Inverse Grayscale",
32  "Hot Iron",
33  "Jet",
34  "Jet Transparent",
35  "Legacy Binary",
36  "Legacy Rainbow Color",
37  "Multilabel",
38  "PET Color",
39  "PET 20",
40  "END_OF_ARRAY" // Do not add typenames after this entry (see QmitkDataManagerView::ColormapMenuAboutToShow())
41 };
42 
43 mitk::LookupTable::LookupTable() : m_Window(0.0), m_Level(0.0), m_Opacity(1.0), m_type(mitk::LookupTable::GRAYSCALE)
44 {
47 }
48 
50  : itk::DataObject(), m_LookupTable(vtkSmartPointer<vtkLookupTable>::New())
51 {
52  m_LookupTable->DeepCopy(other.m_LookupTable);
53 }
54 
56 {
57 }
58 
59 void mitk::LookupTable::SetVtkLookupTable(vtkSmartPointer<vtkLookupTable> lut)
60 {
61  if ((!lut) || (m_LookupTable == lut))
62  {
63  return;
64  }
65 
66  m_LookupTable = lut;
67  this->Modified();
68 }
69 
71 {
72  if (m_type == type)
73  return;
74 
75  switch (type)
76  {
78  this->BuildGrayScaleLookupTable();
79  break;
81  this->BuildInverseGrayScaleLookupTable();
82  break;
84  this->BuildHotIronLookupTable();
85  break;
87  this->BuildJetLookupTable();
88  break;
90  this->BuildJetLookupTable(true);
91  break;
93  this->BuildLegacyBinaryLookupTable();
94  break;
96  this->BuildMultiLabelLookupTable();
97  break;
99  this->BuildPETColorLookupTable();
100  break;
102  this->BuildPET20LookupTable();
103  break;
105  this->BuildLegacyRainbowColorLookupTable();
106  break;
107  default:
108  MITK_ERROR << "non-existing colormap";
109  return;
110  }
111 
112  m_type = type;
113 }
114 
115 void mitk::LookupTable::SetType(const std::string &typeName)
116 {
117  int i = 0;
118  std::string lutType = this->typenameList[i];
119 
120  while (lutType != "END_OF_ARRAY")
121  {
122  if (lutType == typeName)
123  {
124  this->SetType(static_cast<mitk::LookupTable::LookupTableType>(i));
125  }
126 
127  lutType = this->typenameList[++i];
128  }
129 }
130 
132 {
133  return std::string(typenameList[(int)m_type]);
134 }
135 
137 {
138  int noValues = m_LookupTable->GetNumberOfTableValues();
139 
140  double rgba[4];
141 
142  for (int i = 0; i < noValues; i++)
143  {
144  m_LookupTable->GetTableValue(i, rgba);
145  rgba[3] = opacity;
146  m_LookupTable->SetTableValue(i, rgba);
147  }
148  this->Modified(); // need to call modified, since LookupTableProperty seems to be unchanged so no widget-update is
149  // executed
150 }
151 
152 void mitk::LookupTable::ChangeOpacity(int index, float opacity)
153 {
154  int noValues = m_LookupTable->GetNumberOfTableValues();
155  if (index > noValues)
156  {
157  MITK_INFO << "could not change opacity. index exceed size of lut ... " << std::endl;
158  return;
159  }
160 
161  double rgba[4];
162 
163  m_LookupTable->GetTableValue(index, rgba);
164  rgba[3] = opacity;
165  m_LookupTable->SetTableValue(index, rgba);
166 
167  this->Modified(); // need to call modified, since LookupTableProperty seems to be unchanged so no widget-update is
168  // executed
169 }
170 
171 void mitk::LookupTable::GetColor(double value, double rgb[3])
172 {
173  this->GetVtkLookupTable()->GetColor(value, rgb);
174 }
175 
176 void mitk::LookupTable::GetTableValue(int index, double rgba[4])
177 {
178  this->GetVtkLookupTable()->GetTableValue(index, rgba);
179 }
180 
181 void mitk::LookupTable::SetTableValue(int index, double rgba[4])
182 {
183  this->GetVtkLookupTable()->SetTableValue(index, rgba);
184 }
185 
186 vtkSmartPointer<vtkLookupTable> mitk::LookupTable::GetVtkLookupTable() const
187 {
188  return m_LookupTable;
189 }
190 
192 {
193  return m_LookupTable->GetPointer(0);
194 }
195 
200 {
201  if (m_LookupTable == other.GetVtkLookupTable())
202  return true;
203  vtkLookupTable *olut = other.GetVtkLookupTable();
204  if (olut == nullptr)
205  return false;
206 
207  bool equal = (m_LookupTable->GetNumberOfColors() == olut->GetNumberOfColors()) &&
208  (m_LookupTable->GetTableRange()[0] == olut->GetTableRange()[0]) &&
209  (m_LookupTable->GetTableRange()[1] == olut->GetTableRange()[1]) &&
210  (m_LookupTable->GetHueRange()[0] == olut->GetHueRange()[0]) &&
211  (m_LookupTable->GetHueRange()[1] == olut->GetHueRange()[1]) &&
212  (m_LookupTable->GetSaturationRange()[0] == olut->GetSaturationRange()[0]) &&
213  (m_LookupTable->GetSaturationRange()[1] == olut->GetSaturationRange()[1]) &&
214  (m_LookupTable->GetValueRange()[0] == olut->GetValueRange()[0]) &&
215  (m_LookupTable->GetValueRange()[1] == olut->GetValueRange()[1]) &&
216  (m_LookupTable->GetAlphaRange()[0] == olut->GetAlphaRange()[0]) &&
217  (m_LookupTable->GetAlphaRange()[1] == olut->GetAlphaRange()[1]) &&
218  (m_LookupTable->GetRamp() == olut->GetRamp()) && (m_LookupTable->GetScale() == olut->GetScale()) &&
219  (m_LookupTable->GetAlpha() == olut->GetAlpha()) &&
220  (m_LookupTable->GetTable()->GetNumberOfTuples() == olut->GetTable()->GetNumberOfTuples());
221  if (equal == false)
222  return false;
223  for (vtkIdType i = 0; i < m_LookupTable->GetNumberOfTableValues(); i++)
224  {
225  bool tvequal = (m_LookupTable->GetTableValue(i)[0] == olut->GetTableValue(i)[0]) &&
226  (m_LookupTable->GetTableValue(i)[1] == olut->GetTableValue(i)[1]) &&
227  (m_LookupTable->GetTableValue(i)[2] == olut->GetTableValue(i)[2]) &&
228  (m_LookupTable->GetTableValue(i)[3] == olut->GetTableValue(i)[3]);
229  if (tvequal == false)
230  return false;
231  }
232  return true;
233 }
234 
239 {
240  return !(*this == other);
241 }
242 
247 {
248  if (this == &LookupTable)
249  {
250  return *this;
251  }
252  else
253  {
254  m_LookupTable = LookupTable.GetVtkLookupTable();
255  return *this;
256  }
257 }
258 
260 {
261  if (this->GetSource())
262  {
263  this->GetSource()->UpdateOutputInformation();
264  }
265 }
266 
268 {
269 }
270 
272 {
273  return false;
274 }
275 
277 {
278  // normally we should check if the requested region lies within the
279  // largest possible region. Since for lookup-tables we assume, that the
280  // requested region is always the largest possible region, we can always
281  // return true!
282  return true;
283 }
284 
285 void mitk::LookupTable::SetRequestedRegion(const itk::DataObject *)
286 {
287  // not implemented, since we always want to have the RequestedRegion
288  // to be set to LargestPossibleRegion
289 }
290 
291 vtkSmartPointer<vtkColorTransferFunction> mitk::LookupTable::CreateColorTransferFunction()
292 {
293  vtkSmartPointer<vtkColorTransferFunction> colorFunction = vtkSmartPointer<vtkColorTransferFunction>::New();
294 
295  mitk::LookupTable::RawLookupTableType *rawLookupTable = this->GetRawLookupTable();
296  int num_of_values = m_LookupTable->GetNumberOfTableValues();
297 
298  auto cols = new double[3 * num_of_values];
299  double *colsHead = cols;
300 
301  for (int i = 0; i < num_of_values; ++i)
302  {
303  *cols = static_cast<double>(*rawLookupTable) / 255.0;
304  ++cols;
305  ++rawLookupTable;
306  *cols = static_cast<double>(*rawLookupTable) / 255.0;
307  ++cols;
308  ++rawLookupTable;
309  *cols = static_cast<double>(*rawLookupTable) / 255.0;
310  ++cols;
311  ++rawLookupTable;
312  ++rawLookupTable;
313  }
314  colorFunction->BuildFunctionFromTable(
315  m_LookupTable->GetTableRange()[0], m_LookupTable->GetTableRange()[1], num_of_values, colsHead);
316  return colorFunction;
317 }
318 
319 void mitk::LookupTable::CreateColorTransferFunction(vtkColorTransferFunction *&colorFunction)
320 {
321  colorFunction = this->CreateColorTransferFunction();
322 }
323 
324 vtkSmartPointer<vtkPiecewiseFunction> mitk::LookupTable::CreateOpacityTransferFunction()
325 {
326  vtkSmartPointer<vtkPiecewiseFunction> opacityFunction = vtkSmartPointer<vtkPiecewiseFunction>::New();
327 
328  mitk::LookupTable::RawLookupTableType *rgba = this->GetRawLookupTable();
329  int num_of_values = m_LookupTable->GetNumberOfTableValues();
330 
331  auto alphas = new double[num_of_values];
332  double *alphasHead = alphas;
333 
334  rgba += 3;
335  for (int i = 0; i < num_of_values; ++i)
336  {
337  *alphas = static_cast<double>(*rgba) / 255.0;
338  ++alphas;
339  rgba += 4;
340  }
341 
342  opacityFunction->BuildFunctionFromTable(
343  m_LookupTable->GetTableRange()[0], m_LookupTable->GetTableRange()[1], num_of_values, alphasHead);
344  return opacityFunction;
345 }
346 
347 void mitk::LookupTable::CreateOpacityTransferFunction(vtkPiecewiseFunction *&opacityFunction)
348 {
349  opacityFunction = this->CreateOpacityTransferFunction();
350 }
351 
352 vtkSmartPointer<vtkPiecewiseFunction> mitk::LookupTable::CreateGradientTransferFunction()
353 {
354  vtkSmartPointer<vtkPiecewiseFunction> gradientFunction = vtkSmartPointer<vtkPiecewiseFunction>::New();
355 
356  mitk::LookupTable::RawLookupTableType *rgba = this->GetRawLookupTable();
357  int num_of_values = m_LookupTable->GetNumberOfTableValues();
358 
359  auto alphas = new double[num_of_values];
360  double *alphasHead = alphas;
361 
362  rgba += 3;
363  for (int i = 0; i < num_of_values; ++i)
364  {
365  *alphas = static_cast<double>(*rgba) / 255.0;
366  ++alphas;
367  rgba += 4;
368  }
369 
370  gradientFunction->BuildFunctionFromTable(
371  m_LookupTable->GetTableRange()[0], m_LookupTable->GetTableRange()[1], num_of_values, alphasHead);
372  return gradientFunction;
373 }
374 
375 void mitk::LookupTable::CreateGradientTransferFunction(vtkPiecewiseFunction *&gradientFunction)
376 {
377  gradientFunction = this->CreateGradientTransferFunction();
378 }
379 
380 void mitk::LookupTable::PrintSelf(std::ostream &os, itk::Indent indent) const
381 {
382  os << indent;
383  m_LookupTable->PrintHeader(os, vtkIndent());
384 }
385 
386 itk::LightObject::Pointer mitk::LookupTable::InternalClone() const
387 {
388  itk::LightObject::Pointer result(new Self(*this));
389  result->UnRegister();
390  return result;
391 }
392 
394 {
395  vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
396  lut->SetRampToLinear();
397  lut->SetSaturationRange(0.0, 0.0);
398  lut->SetHueRange(0.0, 0.0);
399  lut->SetValueRange(0.0, 1.0);
400  lut->Build();
401 
402  m_LookupTable = lut;
403  this->Modified();
404 }
405 
407 {
408  vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
409  lut->SetRampToLinear();
410  lut->SetSaturationRange(0.0, 0.0);
411  lut->SetHueRange(0.0, 0.0);
412  lut->SetValueRange(0.0, 1.0);
413  lut->Build();
414  lut->SetTableValue(0, 0.0, 0.0, 0.0, 0.0);
415 
416  m_LookupTable = lut;
417  this->Modified();
418 }
419 
421 {
422  vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
423  lut->SetTableRange(0, 1);
424  lut->SetSaturationRange(0, 0);
425  lut->SetHueRange(0, 0);
426  lut->SetValueRange(1, 0);
427  lut->SetAlphaRange(1, 0);
428  lut->Build();
429 
430  m_LookupTable = lut;
431  this->Modified();
432 }
433 
435 {
436  vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
437  lut->SetNumberOfTableValues(256);
438  lut->Build();
439 
440  for (int i = 0; i < 256; i++)
441  {
442  lut->SetTableValue(
443  i, (double)HotIron[i][0] / 255.0, (double)HotIron[i][1] / 255.0, (double)HotIron[i][2] / 255.0, 1.0);
444  }
445 
446  m_LookupTable = lut;
447  this->Modified();
448 }
449 
451 {
452  vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
453  lut->SetNumberOfTableValues(256);
454  lut->Build();
455  int i = 0;
456 
457  if (transparent)
458  {
459  // Lowest intensity is transparent
460  lut->SetTableValue(0, (double)Jet[0][0] / 255.0, (double)Jet[0][1] / 255.0, (double)Jet[0][2] / 255.0, 0.0);
461  i = 1;
462  }
463 
464  for (; i < 256; i++)
465  {
466  lut->SetTableValue(i, (double)Jet[i][0] / 255.0, (double)Jet[i][1] / 255.0, (double)Jet[i][2] / 255.0, 1.0);
467  }
468 
469  m_LookupTable = lut;
470  this->Modified();
471 }
472 
474 {
475  vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
476  lut->SetNumberOfTableValues(256);
477  lut->SetTableRange((m_Level - m_Window / 2.0), (m_Level + m_Window / 2.0));
478  lut->Build();
479 
480  for (int i = 0; i < 256; i++)
481  {
482  lut->SetTableValue(
483  i, (double)PETColor[i][0] / 255.0, (double)PETColor[i][1] / 255.0, (double)PETColor[i][2] / 255.0, 1.0);
484  }
485 
486  m_LookupTable = lut;
487  this->Modified();
488 }
489 
491 {
492  vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
493  lut->SetNumberOfTableValues(256);
494  lut->SetTableRange((m_Level - m_Window / 2.0), (m_Level + m_Window / 2.0));
495  lut->Build();
496 
497  for (int i = 0; i < 256; i++)
498  {
499  lut->SetTableValue(i, (double)PET20[i][0] / 255.0, (double)PET20[i][1] / 255.0, (double)PET20[i][2] / 255.0, 1.0);
500  }
501 
502  m_LookupTable = lut;
503  this->Modified();
504 }
505 
507 {
508  vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
509  lut->SetNumberOfTableValues(65536);
510  lut->SetTableRange(0, 65536);
511  lut->SetTableValue(0, 0.0, 0.0, 0.0, 0.0); // background
512 
513  lut->SetTableValue(1, 1.0, 1.0, 0.0, 0.4);
514  lut->SetTableValue(2, 0.0, 1.0, 0.0, 0.4);
515  lut->SetTableValue(3, 0.0, 0.0, 1.0, 0.4);
516  lut->SetTableValue(4, 1.0, 1.0, 0.4, 0.4);
517  lut->SetTableValue(5, 0.0, 0.4, 0.7, 0.4);
518  lut->SetTableValue(6, 1.0, 0.0, 1.0, 0.4);
519 
520  lut->SetTableValue(7, 1.0, 0.5, 0.0, 0.4);
521  lut->SetTableValue(8, 0.0, 1.0, 0.5, 0.4);
522  lut->SetTableValue(9, 0.5, 0.0, 1.0, 0.4);
523  lut->SetTableValue(10, 1.0, 1.0, 0.5, 0.4);
524  lut->SetTableValue(11, 0.5, 1.0, 1.0, 0.4);
525  lut->SetTableValue(12, 1.0, 0.5, 0.6, 0.4);
526  lut->SetTableValue(13, 1.0, 0.3, 0.3, 0.4);
527  lut->SetTableValue(14, 0.4, 0.7, 1.0, 0.4);
528  lut->SetTableValue(15, 0.4, 0.5, 1.0, 0.4);
529  lut->SetTableValue(16, 0.8, 0.5, 1.0, 0.4);
530  lut->SetTableValue(17, 1.0, 0.3, 1.0, 0.4);
531  lut->SetTableValue(18, 1.0, 0.5, 0.6, 0.4);
532  lut->SetTableValue(19, 1.0, 0.5, 0.4, 0.4);
533  lut->SetTableValue(20, 0.4, 0.5, 0.4, 0.4);
534  lut->SetTableValue(21, 1.0, 0.5, 0.76, 0.4);
535  lut->SetTableValue(22, 0.76, 0.4, 0.4, 0.4);
536  lut->SetTableValue(23, 1.0, 0.5, 0.4, 0.4);
537  lut->SetTableValue(24, 0.76, 0.3, 0.4, 0.4);
538  lut->SetTableValue(25, 1.0, 0.3, 0.4, 0.4);
539 
540  for (int i = 26; i < 65536; i++)
541  {
542  if (i % 12 == 0)
543  lut->SetTableValue(i, 1.0, 0.0, 0.0, 0.4);
544  else if (i % 12 == 1)
545  lut->SetTableValue(i, 0.0, 1.0, 0.0, 0.4);
546  else if (i % 12 == 2)
547  lut->SetTableValue(i, 0.0, 0.0, 1.0, 0.4);
548  else if (i % 12 == 3)
549  lut->SetTableValue(i, 1.0, 1.0, 0.0, 0.4);
550  else if (i % 12 == 4)
551  lut->SetTableValue(i, 0.0, 1.0, 1.0, 0.4);
552  else if (i % 12 == 5)
553  lut->SetTableValue(i, 1.0, 0.0, 1.0, 0.4);
554  else if (i % 12 == 6)
555  lut->SetTableValue(i, 1.0, 0.5, 0.0, 0.4);
556  else if (i % 12 == 7)
557  lut->SetTableValue(i, 0.0, 1.0, 0.5, 0.4);
558  else if (i % 12 == 8)
559  lut->SetTableValue(i, 0.5, 0.0, 1.0, 0.4);
560  else if (i % 12 == 9)
561  lut->SetTableValue(i, 1.0, 1.0, 0.5, 0.4);
562  else if (i % 12 == 10)
563  lut->SetTableValue(i, 0.5, 1.0, 1.0, 0.4);
564  else if (i % 12 == 11)
565  lut->SetTableValue(i, 1.0, 0.5, 1.0, 0.4);
566  }
567 
568  m_LookupTable = lut;
569  this->Modified();
570 }
571 
573 {
574  vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
575  lut->SetRampToLinear();
576  lut->SetHueRange(0.6667, 0.0);
577  lut->SetTableRange(0.0, 20.0);
578  lut->Build();
579 
580  m_LookupTable = lut;
581  this->Modified();
582 }
virtual void SetTableValue(int index, double rgba[4])
SetTableValue convenience method wrapping the vtkLookupTable::SetTableValue() method.
virtual vtkSmartPointer< vtkLookupTable > GetVtkLookupTable() const
GetVtkLookupTable Getter for the internally wrapped vtkLookupTable.
virtual void BuildGrayScaleLookupTable()
virtual bool VerifyRequestedRegion() override
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
virtual void BuildInverseGrayScaleLookupTable()
#define MITK_ERROR
Definition: mitkLogMacros.h:24
LookupTableType
The LookupTableType enum for different predefined lookup tables.
virtual void BuildPETColorLookupTable()
virtual RawLookupTableType * GetRawLookupTable() const
GetRawLookupTable Getter for the raw lookuptable array.
DataCollection - Class to facilitate loading/accessing structured data.
static const char *const typenameList[]
virtual void ChangeOpacityForAll(float opacity)
ChangeOpacityForAll Set the opacity for all table values.
virtual void SetRequestedRegionToLargestPossibleRegion() override
virtual void GetTableValue(int index, double rgba[4])
GetTableValue convenience method wrapping the vtkLookupTable::GetTableValue() method.
static const int HotIron[256][3]
Definition: HotIron.h:20
virtual bool operator==(const mitk::LookupTable &LookupTable) const
equality operator implementation
virtual void SetRequestedRegion(const itk::DataObject *data) override
virtual void UpdateOutputInformation() override
vtkSmartPointer< vtkPiecewiseFunction > CreateGradientTransferFunction()
virtual void BuildLegacyRainbowColorLookupTable()
virtual void BuildJetLookupTable(bool transparent=false)
virtual LookupTable & operator=(const LookupTable &LookupTable)
implementation necessary because operator made private in itk::Object
static const int Jet[256][3]
Definition: Jet.h:22
vtkSmartPointer< vtkPiecewiseFunction > CreateOpacityTransferFunction()
virtual bool operator!=(const LookupTable &LookupTable) const
non equality operator implementation
virtual void BuildPET20LookupTable()
vtkSmartPointer< vtkLookupTable > m_LookupTable
virtual void BuildHotIronLookupTable()
void PrintSelf(std::ostream &os, itk::Indent indent) const override
unsigned char RawLookupTableType
RawLookupTableType raw lookuptable typedef for convenience.
vtkSmartPointer< vtkColorTransferFunction > CreateColorTransferFunction()
virtual void ChangeOpacity(int index, float opacity)
ChangeOpacity Set the opacity for a specific table index.
virtual void GetColor(double value, double rgb[3])
GetColor convenience method wrapping the vtkLookupTable::GetColor() method.
virtual void BuildLegacyBinaryLookupTable()
virtual void SetVtkLookupTable(vtkSmartPointer< vtkLookupTable > lut)
SetVtkLookupTable Setter for the internal lookuptable.
static const int PET20[256][3]
Definition: PET20.h:20
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion() override
virtual const std::string GetActiveTypeAsString()
Return the current look-up table type as a string.
virtual void SetType(const LookupTableType type)
Set the look-up table type by enum (or integer).
virtual void BuildMultiLabelLookupTable()
The LookupTable class mitk wrapper for a vtkLookupTableThis class can be used to color images with a ...
static const int PETColor[256][3]
Definition: PETColor.h:20
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.