Fraxinus  2023.01.05-dev+develop.0da12
An IGT application
cxUnsignedDerivedImage.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 
13 #include "cxUnsignedDerivedImage.h"
14 
15 #include <vtkUnsignedCharArray.h>
16 #include <vtkImageData.h>
17 #include <vtkPointData.h>
18 #include <vtkDoubleArray.h>
19 
20 #include "cxImage.h"
21 
22 #include <vtkImageResample.h>
23 #include <vtkImageClip.h>
24 #include "vtkImageShiftScale.h"
25 
26 #include "cxImage.h"
27 #include "cxUtilHelpers.h"
28 #include "cxImageTF3D.h"
29 #include "cxImageLUT2D.h"
31 
32 
34 #include "cxLogger.h"
35 
36 typedef vtkSmartPointer<vtkDoubleArray> vtkDoubleArrayPtr;
37 
38 namespace cx
39 {
40 
42 {
43  boost::shared_ptr<UnsignedDerivedImage> retval;
44  retval.reset(new UnsignedDerivedImage(base));
45  return retval;
46 }
47 
48 UnsignedDerivedImage::UnsignedDerivedImage(ImagePtr base) : Image(base->getUid()+"_u", vtkImageDataPtr(), base->getName())
49 {
50  this->mBase = base;
51 
52  // redirected signals:
53  connect(base.get(), SIGNAL(transformChanged()), this, SIGNAL(transformChanged()));
54  connect(base.get(), SIGNAL(propertiesChanged()), this, SIGNAL(propertiesChanged()));
55  connect(base.get(), SIGNAL(clipPlanesChanged()), this, SIGNAL(clipPlanesChanged()));
56  connect(base.get(), SIGNAL(cropBoxChanged()), this, SIGNAL(cropBoxChanged()));
57 
58  // override signals:
59  connect(base.get(), SIGNAL(transferFunctionsChanged()), this, SLOT(unsignedTransferFunctionsChangedSlot()));
60  connect(base.get(), SIGNAL(vtkImageDataChanged()), this, SLOT(unsignedImageChangedSlot()));
61 
62  connect(this, SIGNAL(transferFunctionsChanged()), this, SLOT(testSlot()));
63  this->unsignedImageChangedSlot();
64  this->unsignedTransferFunctionsChangedSlot();
65 }
66 
67 void UnsignedDerivedImage::testSlot()
68 {
69 }
70 
71 void UnsignedDerivedImage::unsignedTransferFunctionsChangedSlot()
72 {
73  ImagePtr base = mBase.lock();
74  if (!base)
75  return;
76 
77 
78  // this is a slow operation, triggered every time the mBase is changed. Take care.
79 
80  int shift = this->findShift();
81 
82  ImageTF3DPtr TF3D = base->getTransferFunctions3D()->createCopy();
83  ImageLUT2DPtr LUT2D = base->getLookupTable2D()->createCopy();
84  TF3D->shift(shift);
85  LUT2D->shift(shift);
86  this->setLookupTable2D(LUT2D);
87  this->setTransferFunctions3D(TF3D);
88 }
89 
90 void UnsignedDerivedImage::unsignedImageChangedSlot()
91 {
92  this->setVtkImageData(this->convertImage());
93 }
94 
95 int UnsignedDerivedImage::findShift()
96 {
97  ImagePtr base = mBase.lock();
98  if (!base)
99  return 0;
100  vtkImageDataPtr input = base->getBaseVtkImageData();
101 
102  if (input->GetScalarTypeMin() >= 0)
103  return 0;
104 
105  // start by shifting up to zero
106  int shift = -input->GetScalarRange()[0];
107  // if CT: always shift by 1024 (houndsfield units definition)
108  if (base->getModality() == imCT)
109  shift = 1024;
110  return shift;
111 }
112 
113 vtkImageDataPtr UnsignedDerivedImage::convertImage()
114 {
115  vtkImageDataPtr retval;
116 
117  ImagePtr base = mBase.lock();
118  if (!base)
119  return retval;
120 
121  int shift = this->findShift();
122  vtkImageDataPtr input = base->getBaseVtkImageData();
123 
124  vtkImageShiftScalePtr cast = vtkImageShiftScalePtr::New();
125  cast->SetInputData(input);
126  cast->ClampOverflowOn();
127 
128  cast->SetShift(shift);
129 
130  // total intensity range of voxels:
131  double range = input->GetScalarRange()[1] - input->GetScalarRange()[0];
132 
133  // to to fit within smallest type
134  if (range <= VTK_UNSIGNED_SHORT_MAX-VTK_UNSIGNED_SHORT_MIN)
135  cast->SetOutputScalarType(VTK_UNSIGNED_SHORT);
136  else if (range <= VTK_UNSIGNED_INT_MAX-VTK_UNSIGNED_INT_MIN)
137  cast->SetOutputScalarType(VTK_UNSIGNED_INT);
138 // else if (range <= VTK_UNSIGNED_LONG_MAX-VTK_UNSIGNED_LONG_MIN) // not supported by vtk - it seems (crash in rendering)
139 // cast->SetOutputScalarType(VTK_UNSIGNED_LONG);
140  else
141  cast->SetOutputScalarType(VTK_UNSIGNED_INT);
142 
143  cast->Update();
144 // if (verbose)
145  report(QString("Converting image %1 from %2 to %3").arg(this->getName()).arg(input->GetScalarTypeAsString()).arg(cast->GetOutput()->GetScalarTypeAsString()));
146  retval = cast->GetOutput();
147  return retval;
148 }
149 
151 {
153 }
154 
155 }
Image(const QString &uid, const vtkImageDataPtr &data, const QString &name="")
Definition: cxImage.cpp:106
virtual void setTransferFunctions3D(ImageTF3DPtr transferFuntion)
Definition: cxImage.cpp:311
vtkSmartPointer< class vtkImageShiftScale > vtkImageShiftScalePtr
virtual void setVtkImageData(const vtkImageDataPtr &data, bool resetTransferFunctions=true)
Definition: cxImage.cpp:268
void propertiesChanged()
emitted when one of the metadata properties (uid, name etc) changes
#define CALL_IN_WEAK_PTR(weak_base, func, defarg)
virtual void setLookupTable2D(ImageLUT2DPtr imageLookupTable2D)
Definition: cxImage.cpp:330
void transformChanged()
emitted when transform is changed
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:27
static ImagePtr create(ImagePtr base)
void clipPlanesChanged()
boost::shared_ptr< class ImageLUT2D > ImageLUT2DPtr
vtkSmartPointer< vtkDoubleArray > vtkDoubleArrayPtr
void transferFunctionsChanged()
emitted when image transfer functions in 2D or 3D are changed.
Identification of a Coordinate system.
Class that holds an unsigned version of a base Image.
virtual QString getName() const
void report(QString msg)
Definition: cxLogger.cpp:69
void vtkImageDataChanged(QString uid=QString())
emitted when the vktimagedata are invalidated and must be retrieved anew.
void cropBoxChanged()
imCT
vtkSmartPointer< class vtkImageData > vtkImageDataPtr
boost::shared_ptr< class ImageTF3D > ImageTF3DPtr
virtual CoordinateSystem getCoordinateSystem()
Namespace for all CustusX production code.