38 #include "vtkStandardImageRepresenter.h"
40 #include <vtkStructuredPointsReader.h>
41 #include <vtkStructuredPointsWriter.h>
42 #include <vtkPointData.h>
43 #include <vtkDataArray.h>
44 #include <vtkVersion.h>
46 #include "CommonTypes.h"
47 #include "HDF5Utils.h"
48 #include "StatismoUtils.h"
52 template<
class TScalar,
unsigned PixelDimensions>
53 vtkStandardImageRepresenter<TScalar, PixelDimensions>::vtkStandardImageRepresenter(
54 DatasetConstPointerType reference) :
55 m_reference(vtkStructuredPoints::New()) {
56 this->SetReference(reference);
59 template<
class TScalar,
unsigned PixelDimensions>
60 vtkStandardImageRepresenter<TScalar, PixelDimensions>::~vtkStandardImageRepresenter() {
62 if (m_reference != 0) {
63 m_reference->Delete();
68 template<
class TScalar,
unsigned PixelDimensions>
69 vtkStandardImageRepresenter<TScalar, PixelDimensions>*
70 vtkStandardImageRepresenter<TScalar, PixelDimensions>::Clone()
const {
72 return Create(m_reference);
75 template<
class TScalar,
unsigned PixelDimensions>
76 void vtkStandardImageRepresenter<TScalar, PixelDimensions>::Load(
const H5::Group& fg) {
78 vtkStructuredPoints* ref = 0;
81 if (repName ==
"vtkStructuredPointsRepresenter" || repName ==
"itkImageRepresenter" || repName ==
"itkVectorImageRepresenter") {
82 ref = LoadRefLegacy(fg);
86 this->SetReference(ref);
89 template<
class TScalar,
unsigned PixelDimensions>
90 vtkStructuredPoints* vtkStandardImageRepresenter<TScalar, PixelDimensions>::LoadRef(
const H5::Group& fg)
const {
93 if (type !=
"IMAGE") {
94 throw StatisticalModelException(
95 (std::string(
"Cannot load representer data: The ")
96 +
"representer specified in the given hdf5 file is of the wrong type: ("
97 + type +
", expected IMAGE)").c_str());
100 statismo::VectorType originVec;
106 if (imageDimension > 3) {
107 throw StatisticalModelException(
108 "this representer does not support images of dimensionality > 3");
112 double origin[3] = { 0, 0, 0 };
113 for (
unsigned i = 0; i < imageDimension; i++) {
114 origin[i] = originVec[i];
117 statismo::VectorType spacingVec;
119 float spacing[3] = { 0, 0, 0 };
120 for (
unsigned i = 0; i < imageDimension; i++) {
121 spacing[i] = spacingVec[i];
124 typename statismo::GenericEigenType<int>::VectorType sizeVec;
125 HDF5Utils::readVectorOfType<int>(fg,
"size", sizeVec);
126 int size[3] = { 1, 1, 1 };
127 for (
unsigned i = 0; i < imageDimension; i++) {
128 size[i] = sizeVec[i];
131 H5::Group pdGroup = fg.openGroup(
"./pointData");
133 typename statismo::GenericEigenType<double>::MatrixType pixelMat;
134 HDF5Utils::readMatrixOfType<double>(pdGroup,
"pixelValues", pixelMat);
135 H5::DataSet ds = pdGroup.openDataSet(
"pixelValues");
139 if (statismo::GetDataTypeId<TScalar>() != datatype) {
141 <<
"Warning: The datatype specified for the scalars does not match the TPixel template argument used in this representer."
146 vtkStructuredPoints* newImage = vtkStructuredPoints::New();
147 newImage->SetDimensions(size[0], size[1], size[2]);
149 newImage->SetExtent(0, size[0] - 1, 0, size[1] - 1, 0, size[2] - 1);
151 newImage->SetOrigin(origin[0], origin[1], origin[2]);
152 newImage->SetSpacing(spacing[0], spacing[1], spacing[2]);
155 case statismo::SIGNED_CHAR:
156 #if (VTK_MAJOR_VERSION == 5 )
157 newImage->SetScalarTypeToSignedChar();
158 newImage->SetNumberOfScalarComponents( PixelDimensions );
159 newImage->AllocateScalars();
161 newImage->AllocateScalars(VTK_SIGNED_CHAR, PixelDimensions);
164 case statismo::UNSIGNED_CHAR:
165 #if (VTK_MAJOR_VERSION == 5 )
166 newImage->SetScalarTypeToUnsignedChar();
167 newImage->SetNumberOfScalarComponents( PixelDimensions );
168 newImage->AllocateScalars();
170 newImage->AllocateScalars(VTK_UNSIGNED_CHAR, PixelDimensions);
173 case statismo::SIGNED_SHORT:
174 #if (VTK_MAJOR_VERSION == 5 )
175 newImage->SetScalarTypeToShort();
176 newImage->SetNumberOfScalarComponents( PixelDimensions );
177 newImage->AllocateScalars();
179 newImage->AllocateScalars(VTK_SHORT, PixelDimensions);
182 case statismo::UNSIGNED_SHORT:
183 #if (VTK_MAJOR_VERSION == 5 )
184 newImage->SetScalarTypeToUnsignedChar();
185 newImage->SetNumberOfScalarComponents( PixelDimensions );
186 newImage->AllocateScalars();
188 newImage->AllocateScalars(VTK_UNSIGNED_SHORT, PixelDimensions);
191 case statismo::SIGNED_INT:
192 #if (VTK_MAJOR_VERSION == 5 )
193 newImage->SetScalarTypeToInt();
194 newImage->SetNumberOfScalarComponents( PixelDimensions );
195 newImage->AllocateScalars();
197 newImage->AllocateScalars(VTK_INT, PixelDimensions);
200 case statismo::UNSIGNED_INT:
201 #if (VTK_MAJOR_VERSION == 5 )
202 newImage->SetScalarTypeToUnsignedInt();
203 newImage->SetNumberOfScalarComponents( PixelDimensions );
204 newImage->AllocateScalars();
206 newImage->AllocateScalars(VTK_UNSIGNED_INT, PixelDimensions);
209 case statismo::FLOAT:
210 #if (VTK_MAJOR_VERSION == 5 )
211 newImage->SetScalarTypeToFloat();
212 newImage->SetNumberOfScalarComponents( PixelDimensions );
213 newImage->AllocateScalars();
215 newImage->AllocateScalars(VTK_FLOAT, PixelDimensions);
219 case statismo::DOUBLE:
220 #if (VTK_MAJOR_VERSION == 5 )
221 newImage->SetScalarTypeToDouble();
222 newImage->SetNumberOfScalarComponents( PixelDimensions );
223 newImage->AllocateScalars();
225 newImage->AllocateScalars(VTK_DOUBLE, PixelDimensions);
231 "the datatype found in the statismo model cannot be used for the vtkStandardImageRepresenter");
234 for (
int i = 0; i < size[2]; i++) {
235 for (
int j = 0; j < size[1]; j++) {
236 for (
int k = 0; k < size[0]; k++) {
237 unsigned index = size[1] * size[0] * i + size[0] * j + k;
239 static_cast<TScalar*
>(newImage->GetScalarPointer(k, j,
241 for (
unsigned d = 0; d < PixelDimensions; d++) {
242 scalarPtr[d] = pixelMat(d, index);
253 template<
class TScalar,
unsigned PixelDimensions>
254 vtkStructuredPoints* vtkStandardImageRepresenter<TScalar, PixelDimensions>::LoadRefLegacy(
const H5::Group& fg)
const {
256 vtkStructuredPoints* ref = vtkStructuredPoints::New();
258 std::string tmpfilename = statismo::Utils::CreateTmpName(
".vtk");
262 std::remove(tmpfilename.c_str());
264 vtkStructuredPointsReader* reader = vtkStructuredPointsReader::New();
265 reader->SetFileName(tmpfilename.c_str());
267 if (reader->GetErrorCode() != 0) {
268 throw StatisticalModelException((std::string(
"Could not read file ") + tmpfilename).c_str());
271 ref->DeepCopy(reader->GetOutput());
279 template<
class TScalar,
unsigned PixelDimensions>
280 statismo::VectorType vtkStandardImageRepresenter<TScalar, PixelDimensions>::PointToVector(
281 const PointType& pt)
const {
284 for (
unsigned i = 0; i < 3; i++) {
290 template<
class TScalar,
unsigned PixelDimensions>
291 typename vtkStandardImageRepresenter<TScalar, PixelDimensions>::DatasetPointerType vtkStandardImageRepresenter<
292 TScalar, PixelDimensions>::DatasetToSample(
293 DatasetConstPointerType dataset)
const {
295 vtkStructuredPoints* clone = vtkStructuredPoints::New();
296 clone->DeepCopy(const_cast<vtkStructuredPoints*>(dataset));
298 if (const_cast<vtkStructuredPoints*>(m_reference)->GetNumberOfPoints()
299 != const_cast<vtkStructuredPoints*>(dataset)->GetNumberOfPoints()) {
300 throw StatisticalModelException(
301 "The dataset need to have the same number of points as the reference");
307 template<
class TScalar,
unsigned PixelDimensions>
308 VectorType vtkStandardImageRepresenter<TScalar, PixelDimensions>::SampleToSampleVector(
309 DatasetConstPointerType _sp)
const {
311 vtkStructuredPoints* reference =
312 const_cast<vtkStructuredPoints*
>(this->m_reference);
313 vtkStructuredPoints* sp =
const_cast<vtkStructuredPoints*
>(_sp);
315 if (reference->GetNumberOfPoints() != sp->GetNumberOfPoints()) {
316 throw StatisticalModelException(
317 "The sample does not have the correct number of points");
320 VectorType sample = VectorType::Zero(
321 m_reference->GetNumberOfPoints() * PixelDimensions);
323 vtkDataArray* dataArray = sp->GetPointData()->GetArray(0);
328 for (
unsigned i = 0; i < m_reference->GetNumberOfPoints(); i++) {
330 double val[PixelDimensions];
331 dataArray->GetTuple(i, val);
332 for (
unsigned d = 0; d < PixelDimensions; d++) {
333 unsigned idx = MapPointIdToInternalIdx(i, d);
334 sample(idx) = val[d];
340 template<
class TScalar,
unsigned PixelDimensions>
341 typename vtkStandardImageRepresenter<TScalar, PixelDimensions>::DatasetPointerType vtkStandardImageRepresenter<
342 TScalar, PixelDimensions>::SampleVectorToSample(
343 const VectorType& sample)
const {
344 vtkStructuredPoints* sp = vtkStructuredPoints::New();
345 vtkStructuredPoints* reference =
346 const_cast<vtkStructuredPoints*
>(m_reference);
347 sp->DeepCopy(reference);
349 vtkDataArray* dataArray = sp->GetPointData()->GetArray(0);
350 for (
unsigned i = 0; i < GetNumberOfPoints(); i++) {
351 double val[PixelDimensions];
352 for (
unsigned d = 0; d < PixelDimensions; d++) {
353 unsigned idx = MapPointIdToInternalIdx(i, d);
354 val[d] = sample(idx);
356 dataArray->SetTuple(i, val);
362 template<
class TScalar,
unsigned PixelDimensions>
363 typename vtkStandardImageRepresenter<TScalar, PixelDimensions>::ValueType vtkStandardImageRepresenter<
364 TScalar, PixelDimensions>::PointSampleFromSample(
365 DatasetConstPointerType sample_,
unsigned ptid)
const {
366 DatasetPointerType sample =
const_cast<DatasetPointerType
>(sample_);
367 if (ptid >= sample->GetNumberOfPoints()) {
368 throw StatisticalModelException(
369 "invalid ptid provided to PointSampleFromSample");
372 double doubleVal[PixelDimensions];
373 sample->GetPointData()->GetScalars()->GetTuple(ptid, doubleVal);
374 ValueType val(PixelDimensions);
377 for (
unsigned i = 0; i < PixelDimensions; i++) {
378 val[i] =
static_cast<TScalar
>(doubleVal[i]);
383 template<
class TScalar,
unsigned PixelDimensions>
384 statismo::VectorType vtkStandardImageRepresenter<TScalar, PixelDimensions>::PointSampleToPointSampleVector(
385 const ValueType& v)
const {
386 VectorType vec(PixelDimensions);
387 for (
unsigned i = 0; i < PixelDimensions; i++) {
388 vec[i] =
const_cast<ValueType&
>(v)[i];
394 template<
class TScalar,
unsigned PixelDimensions>
395 typename vtkStandardImageRepresenter<TScalar, PixelDimensions>::ValueType vtkStandardImageRepresenter<
396 TScalar, PixelDimensions>::PointSampleVectorToPointSample(
397 const VectorType& pointSample)
const {
398 ValueType value(PixelDimensions);
400 for (
unsigned i = 0; i < PixelDimensions; i++)
401 value[i] = pointSample[i];
406 template<
class TScalar,
unsigned Dimensions>
407 void vtkStandardImageRepresenter<TScalar, Dimensions>::Save(
408 const H5::Group& fg)
const {
412 int* size = m_reference->GetDimensions();
413 unsigned imageDimension = 0;
414 if (size[2] == 1 && size[1] == 1)
416 else if (size[2] == 1)
423 double* origin = m_reference->GetOrigin();
424 statismo::VectorType originVec = statismo::VectorType::Zero(imageDimension);
425 for (
unsigned i = 0; i < imageDimension; i++) {
426 originVec(i) = origin[i];
430 double* spacing = m_reference->GetSpacing();
431 statismo::VectorType spacingVec = statismo::VectorType::Zero(
433 for (
unsigned i = 0; i < imageDimension; i++) {
434 spacingVec(i) = spacing[i];
438 statismo::GenericEigenType<int>::VectorType sizeVec =
439 statismo::GenericEigenType<int>::VectorType::Zero(imageDimension);
440 for (
unsigned i = 0; i < imageDimension; i++) {
441 sizeVec(i) = size[i];
443 HDF5Utils::writeVectorOfType<int>(fg,
"size", sizeVec);
446 statismo::MatrixType directionMat = statismo::MatrixType::Identity(
447 imageDimension, imageDimension);
450 typedef statismo::GenericEigenType<double>::MatrixType DoubleMatrixType;
451 DoubleMatrixType pixelMat(GetDimensions(), GetNumberOfPoints());
453 for (
unsigned i = 0; i < static_cast<unsigned>(size[2]); i++) {
454 for (
unsigned j = 0; j < static_cast<unsigned>(size[1]); j++) {
455 for (
unsigned k = 0; k < static_cast<unsigned>(size[0]); k++) {
456 unsigned ind = i * size[1] * size[0] + j * size[0] + k;
458 static_cast<TScalar*
>(m_reference->GetScalarPointer(k,
460 for (
unsigned d = 0; d < GetDimensions(); d++) {
461 pixelMat(d, ind) = pixel[d];
467 H5::Group pdGroup = fg.createGroup(
"pointData");
469 H5::DataSet ds = HDF5Utils::writeMatrixOfType<double>(pdGroup,
470 "pixelValues", pixelMat);
472 statismo::GetDataTypeId<TScalar>());
477 template<
class TScalar,
unsigned Dimensions>
478 unsigned vtkStandardImageRepresenter<TScalar, Dimensions>::GetNumberOfPoints()
const {
479 return GetNumberOfPoints(this->m_reference);
482 template<
class TScalar,
unsigned Dimensions>
483 void vtkStandardImageRepresenter<TScalar, Dimensions>::SetReference(
484 const vtkStructuredPoints* reference) {
486 if (m_reference == 0) {
487 m_reference = vtkStructuredPoints::New();
489 m_reference->DeepCopy(const_cast<vtkStructuredPoints*>(reference));
491 DomainType::DomainPointsListType ptList;
492 for (
unsigned i = 0; i < m_reference->GetNumberOfPoints(); i++) {
493 double* d = m_reference->GetPoint(i);
494 ptList.push_back(vtkPoint(d));
499 template<
class TScalar,
unsigned Dimensions>
500 unsigned vtkStandardImageRepresenter<TScalar, Dimensions>::GetPointIdForPoint(
501 const PointType& pt)
const {
502 assert(m_reference != 0);
503 return this->m_reference->FindPoint(const_cast<double*>(pt.data()));
506 template<
class TScalar,
unsigned Dimensions>
507 unsigned vtkStandardImageRepresenter<TScalar, Dimensions>::GetNumberOfPoints(
508 vtkStructuredPoints* reference) {
509 return reference->GetNumberOfPoints();
static void writeIntAttribute(const H5::H5Object &fg, const char *name, int value)
Definition: HDF5Utils.hxx:406
static H5::DataSet writeMatrix(const H5::CommonFG &fg, const char *name, const MatrixType &matrix)
Definition: HDF5Utils.hxx:248
static std::string readStringAttribute(const H5::H5Object &group, const char *name)
Definition: HDF5Utils.hxx:397
static H5::DataSet writeInt(const H5::CommonFG &fg, const char *name, int value)
Definition: HDF5Utils.hxx:426
Generic Exception class for the statismo Library.
Definition: Exceptions.h:68
static void readVector(const H5::CommonFG &fg, const char *name, unsigned nElements, VectorType &vector)
Definition: HDF5Utils.hxx:296
static H5::DataSet writeVector(const H5::CommonFG &fg, const char *name, const VectorType &vector)
Definition: HDF5Utils.hxx:363
static void getFileFromHDF5(const H5::CommonFG &fg, const char *name, const char *filename)
Definition: HDF5Utils.hxx:462
static int readInt(const H5::CommonFG &fg, const char *name)
Definition: HDF5Utils.hxx:434
static int readIntAttribute(const H5::H5Object &group, const char *name)
Definition: HDF5Utils.hxx:416