CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxMetaImageReader.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 #include "cxMetaImageReader.h"
13 
14 #include <QDir>
15 #include "cxTypeConversions.h"
16 #include <vtkMetaImageReader.h>
17 #include <vtkMetaImageWriter.h>
18 #include <vtkImageChangeInformation.h>
19 #include <vtkImageData.h>
20 #include "cxErrorObserver.h"
21 #include "cxCustomMetaImage.h"
22 #include "cxImage.h"
23 #include "cxLogger.h"
25 #include "cxCoreServices.h"
26 #include "cxPatientModelService.h"
27 
28 namespace cx {
29 
31 {
32  //load the image from file
33  vtkMetaImageReaderPtr reader = vtkMetaImageReaderPtr::New();
34  reader->SetFileName(cstring_cast(filename));
35  reader->ReleaseDataFlagOn();
36 
37  if (!ErrorObserver::checkedRead(reader, filename))
38  return vtkImageDataPtr();
39 
40  vtkImageChangeInformationPtr zeroer = vtkImageChangeInformationPtr::New();
41  zeroer->SetInputConnection(reader->GetOutputPort());
42  zeroer->SetOutputOrigin(0, 0, 0);
43  zeroer->Update();
44  return zeroer->GetOutput();
45 }
46 
48  FileReaderWriterImplService("MetaImageReader", Image::getTypeName(), Image::getTypeName(), "mhd", patientModelService)
49 {
50 }
51 
53 {
54  return false;
55 }
56 
57 bool MetaImageReader::canRead(const QString &type, const QString &filename)
58 {
59  QString fileType = QFileInfo(filename).suffix();
60  return (fileType.compare("mhd", Qt::CaseInsensitive) == 0 || fileType.compare("mha", Qt::CaseInsensitive) == 0);
61 }
62 
64 {
65  return Image::getTypeName();
66 }
67 
68 bool MetaImageReader::readInto(DataPtr data, QString filename)
69 {
70  return this->readInto(boost::dynamic_pointer_cast<Image>(data), filename);
71 }
72 bool MetaImageReader::readInto(ImagePtr image, QString filename)
73 {
74  if (!image)
75  return false;
76 
77  CustomMetaImagePtr customReader = CustomMetaImage::create(filename);
78  Transform3D rMd = customReader->readTransform();
79 
80  vtkImageDataPtr raw = this->loadVtkImageData(filename);
81  if(!raw)
82  return false;
83 
84  image->setVtkImageData(raw);
85 // ImagePtr image(new Image(uid, raw));
86 
87  // RegistrationTransform regTrans(rMd, QFileInfo(filename).lastModified(), "From MHD file");
88  // image->get_rMd_History()->addRegistration(regTrans);
89  image->get_rMd_History()->setRegistration(rMd);
90  image->setModality(customReader->readModality());
91  image->setImageType(customReader->readImageType());
92 
93  bool ok1 = true;
94  bool ok2 = true;
95  double level = customReader->readKey("WindowLevel").toDouble(&ok1);
96  double window = customReader->readKey("WindowWidth").toDouble(&ok2);
97 
98  if (ok1 && ok2)
99  {
100  image->setInitialWindowLevel(window, level);
101  image->resetTransferFunctions();
102  }
103 
104  return true;
105 }
106 
107 DataPtr MetaImageReader::read(const QString& uid, const QString& filename)
108 {
109  ImagePtr image(new Image(uid, vtkImageDataPtr()));
110  this->readInto(image, filename);
111  return std::move(image);
112 }
113 
114 std::vector<DataPtr> MetaImageReader::read(const QString &filename)
115 {
116  std::vector<DataPtr> retval;
117 
118  ImagePtr image = boost::dynamic_pointer_cast<Image>(this->createData(Image::getTypeName(), filename));
119 
120  CustomMetaImagePtr customReader = CustomMetaImage::create(filename);
121  Transform3D rMd = customReader->readTransform();
122 
123  vtkImageDataPtr raw = this->loadVtkImageData(filename);
124  if(!raw)
125  return retval;
126 
127  image->setVtkImageData(raw);
128 // ImagePtr image(new Image(uid, raw));
129 
130  // RegistrationTransform regTrans(rMd, QFileInfo(filename).lastModified(), "From MHD file");
131  // image->get_rMd_History()->addRegistration(regTrans);
132  image->get_rMd_History()->setRegistration(rMd);
133  image->setModality(customReader->readModality());
134  image->setImageType(customReader->readImageType());
135 
136  bool ok1 = true;
137  bool ok2 = true;
138  double level = customReader->readKey("WindowLevel").toDouble(&ok1);
139  double window = customReader->readKey("WindowWidth").toDouble(&ok2);
140 
141  if (ok1 && ok2)
142  {
143  image->setInitialWindowLevel(window, level);
144  image->resetTransferFunctions();
145  }
146 
147  retval.push_back(image);
148  return retval;
149 
150 }
151 
152 void MetaImageReader::write(DataPtr data, const QString& filename)
153 {
154  ImagePtr image = boost::dynamic_pointer_cast<Image>(data);
155  if(!image)
156  {
157  CX_LOG_ERROR() << "MetaImageReader::write: Could not cast data to image";
158  return;
159  }
160  if(!image->getBaseVtkImageData())
161  {
162  CX_LOG_ERROR() << "MetaImageReader::write: cxImage has no VtkImageData";
163  return;
164  }
165  vtkMetaImageWriterPtr writer = vtkMetaImageWriterPtr::New();
166  writer->SetInputData(image->getBaseVtkImageData());
167  writer->SetFileDimensionality(3);
168  writer->SetFileName(cstring_cast(filename));
169  QDir().mkpath(QFileInfo(filename).path());
170 
171 // std::cout << "SAVING MHD COMPRESSED " << filename << std::endl;
172 // writer->SetCompression(true);
173  writer->SetCompression(false);
174 // writer->Update(); // caused writing of (null).0 files - not necessary
175  writer->Write();
176 
177  writer = 0;
178 
179  CustomMetaImagePtr customReader = CustomMetaImage::create(filename);
180  customReader->setTransform(image->get_rMd());
181  customReader->setModality(image->getModality());
182  customReader->setImageType(image->getImageType());
183  customReader->setKey("WindowLevel", qstring_cast(image->getInitialWindowLevel()));
184  customReader->setKey("WindowWidth", qstring_cast(image->getInitialWindowWidth()));
185  customReader->setKey("Creator", QString("CustusX_%1").arg(CustusX_VERSION_STRING));
186 }
187 
188 }
189 
191 {
192  return Image::getTypeName();
193 }
194 
195 bool cx::MetaImageReader::canWrite(const QString &type, const QString &filename) const
196 {
197  return this->canWriteInternal(type, filename);
198 }
QString qstring_cast(const T &val)
DataPtr createData(QString type, QString filename, QString name="") const
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
virtual void write(DataPtr data, const QString &filename)
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:27
vtkSmartPointer< vtkImageChangeInformation > vtkImageChangeInformationPtr
Definition: cxImage.cpp:46
cstring_cast_Placeholder cstring_cast(const T &val)
virtual vtkImageDataPtr loadVtkImageData(QString filename)
virtual bool canRead(const QString &type, const QString &filename)
bool canWrite(const QString &type, const QString &filename) const
boost::shared_ptr< class Data > DataPtr
vtkSmartPointer< class vtkMetaImageReader > vtkMetaImageReaderPtr
boost::shared_ptr< class CustomMetaImage > CustomMetaImagePtr
virtual QString canReadDataType() const
#define CX_LOG_ERROR
Definition: cxLogger.h:99
virtual bool readInto(DataPtr data, QString path)
A volumetric data set.
Definition: cxImage.h:45
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
static QString getTypeName()
Definition: cxImage.h:126
vtkSmartPointer< class vtkMetaImageWriter > vtkMetaImageWriterPtr
QString canWriteDataType() const
static bool checkedRead(vtkSmartPointer< vtkAlgorithm > reader, QString filename)
vtkSmartPointer< class vtkImageData > vtkImageDataPtr
MetaImageReader(PatientModelServicePtr patientModelService)
virtual DataPtr read(const QString &uid, const QString &filename)
bool canWriteInternal(const QString &type, const QString &filename) const
static CustomMetaImagePtr create(QString filename)
Namespace for all CustusX production code.