36 #include <QDomDocument>
38 #include <vtkImageAccumulate.h>
39 #include <vtkImageReslice.h>
40 #include <vtkImageData.h>
41 #include <vtkMatrix4x4.h>
43 #include <vtkPlanes.h>
44 #include <vtkImageResample.h>
45 #include <vtkImageChangeInformation.h>
46 #include <vtkImageClip.h>
47 #include <vtkImageIterator.h>
48 #include <vtkImageShiftScale.h>
79 double Image::ShadingStruct::loadAttribute(QDomNode dataNode, QString name,
double defVal)
81 QString text = dataNode.toElement().attribute(name);
83 double val = text.toDouble(&ok);
91 QDomElement elem = dataNode.toElement();
92 elem.setAttribute(
"on", on);
93 elem.setAttribute(
"ambient", ambient);
94 elem.setAttribute(
"diffuse", diffuse);
95 elem.setAttribute(
"specular", specular);
96 elem.setAttribute(
"specularPower", specularPower);
101 if (dataNode.isNull())
104 on = dataNode.toElement().attribute(
"on").toInt();
106 ambient = loadAttribute(dataNode,
"ambient", ambient);
107 diffuse = loadAttribute(dataNode,
"diffuse", diffuse);
108 specular = loadAttribute(dataNode,
"specular", specular);
109 specularPower = loadAttribute(dataNode,
"specularPower", specularPower);
128 mInitialWindowWidth = -1;
129 mInitialWindowLevel = -1;
136 mImageLookupTable2D.reset();
137 mImageTransferFunctions3D.reset();
147 baseImageDataCopy = vtkImageDataPtr::New();
158 retval->mImageLookupTable2D = mImageLookupTable2D;
159 retval->mImageTransferFunctions3D = mImageTransferFunctions3D;
160 retval->mInitialWindowWidth = mInitialWindowWidth;
161 retval->mInitialWindowLevel = mInitialWindowLevel;
174 ImageTF3DPtr transferFunctions = parentImage->getTransferFunctions3D()->createCopy();
175 ImageLUT2DPtr LUT2D = parentImage->getLookupTable2D()->createCopy();
181 mInitialWindowWidth = parentImage->getInitialWindowWidth();
182 mInitialWindowLevel = parentImage->getInitialWindowLevel();
231 this->blockSignals(
true);
233 this->resetTransferFunction(imageTransferFunctions3D);
234 this->resetTransferFunction(imageLookupTable2D);
236 this->blockSignals(
false);
240 void Image::resetTransferFunction(
ImageLUT2DPtr imageLookupTable2D)
242 if (mImageLookupTable2D)
248 mImageLookupTable2D = imageLookupTable2D;
250 if (mImageLookupTable2D)
258 void Image::resetTransferFunction(
ImageTF3DPtr imageTransferFunctions3D)
260 if (mImageTransferFunctions3D)
266 mImageTransferFunctions3D = imageTransferFunctions3D;
268 if (mImageTransferFunctions3D)
284 this->moveToThread(thread);
295 if (resetTransferFunctions)
302 double windowWidth = mImageLookupTable2D->getWindow();
303 double windowLevel = mImageLookupTable2D->getLevel();
320 if(!this->mImageTransferFunctions3D)
322 return mImageTransferFunctions3D;
327 this->resetTransferFunction(transferFuntion);
332 if(!mImageLookupTable2D)
334 return mImageLookupTable2D;
339 this->resetTransferFunction(imageLookupTable2D);
398 template<
typename scalartype>
static int getRGBMax(
vtkImageDataPtr image)
401 vtkImageIterator<scalartype> iter(image, image->GetExtent());
402 while (!iter.IsAtEnd())
404 typename vtkImageIterator<scalartype>::SpanIterator siter = iter.BeginSpan();
405 while (siter != iter.EndSpan())
436 QDateTime before = QDateTime::currentDateTime();
440 case VTK_UNSIGNED_CHAR:
443 case VTK_UNSIGNED_SHORT:
487 QDomNode imageNode = dataNode;
488 QDomDocument doc = dataNode.ownerDocument();
490 QDomElement tf3DNode = doc.createElement(
"transferfunctions");
492 imageNode.appendChild(tf3DNode);
494 QDomElement lut2DNode = doc.createElement(
"lookuptable2D");
496 imageNode.appendChild(lut2DNode);
498 QDomElement shadingNode = doc.createElement(
"shading");
500 imageNode.appendChild(shadingNode);
506 QDomElement cropNode = doc.createElement(
"crop");
509 imageNode.appendChild(cropNode);
511 QDomElement clipNode = doc.createElement(
"clip");
514 QDomElement planeNode = doc.createElement(
"plane");
519 clipNode.appendChild(planeNode);
521 imageNode.appendChild(clipNode);
523 QDomElement modalityNode = doc.createElement(
"modality");
524 modalityNode.appendChild(doc.createTextNode(
mModality));
525 imageNode.appendChild(modalityNode);
527 QDomElement imageTypeNode = doc.createElement(
"imageType");
528 imageTypeNode.appendChild(doc.createTextNode(
mImageType));
529 imageNode.appendChild(imageTypeNode);
531 QDomElement interpolationNode = doc.createElement(
"vtk_interpolation");
533 imageNode.appendChild(interpolationNode);
535 QDomElement initialWindowNode = doc.createElement(
"initialWindow");
536 initialWindowNode.setAttribute(
"width", mInitialWindowWidth);
537 initialWindowNode.setAttribute(
"level", mInitialWindowLevel);
540 double Image::loadAttribute(QDomNode dataNode, QString name,
double defVal)
542 QString text = dataNode.toElement().attribute(name);
544 double val = text.toDouble(&ok);
564 if (dataNode.isNull())
568 QDomNode transferfunctionsNode = dataNode.namedItem(
"transferfunctions");
569 if (!transferfunctionsNode.isNull())
573 std::cout <<
"Warning: Image::parseXml() found no transferfunctions";
574 std::cout << std::endl;
577 mInitialWindowWidth = this->loadAttribute(dataNode.namedItem(
"initialWindow"),
"width", -1);
578 mInitialWindowLevel = this->loadAttribute(dataNode.namedItem(
"initialWindow"),
"level", -1);
583 mShading.
on = dataNode.namedItem(
"shading").toElement().text().toInt();
585 if (!dataNode.namedItem(
"shadingAmbient").isNull())
586 mShading.
ambient = dataNode.namedItem(
"shadingAmbient").toElement().text().toDouble();
587 if (!dataNode.namedItem(
"shadingDiffuse").isNull())
588 mShading.
diffuse = dataNode.namedItem(
"shadingDiffuse").toElement().text().toDouble();
589 if (!dataNode.namedItem(
"shadingSpecular").isNull())
590 mShading.
specular = dataNode.namedItem(
"shadingSpecular").toElement().text().toDouble();
591 if (!dataNode.namedItem(
"shadingSpecularPower").isNull())
599 QDomElement cropNode = dataNode.namedItem(
"crop").toElement();
600 if (!cropNode.isNull())
606 QDomElement clipNode = dataNode.namedItem(
"clip").toElement();
607 QDomElement clipPlaneNode = clipNode.firstChildElement(
"plane");
608 for (; !clipPlaneNode.isNull(); clipPlaneNode = clipPlaneNode.nextSiblingElement(
"plane"))
610 Vector3D normal = Vector3D::fromString(clipPlaneNode.attribute(
"normal"));
611 Vector3D origin = Vector3D::fromString(clipPlaneNode.attribute(
"origin"));
613 plane->SetNormal(normal.begin());
614 plane->SetOrigin(origin.begin());
618 mModality = dataNode.namedItem(
"modality").toElement().text();
619 mImageType = dataNode.namedItem(
"imageType").toElement().text();
621 QDomElement interpoationNode = dataNode.namedItem(
"vtk_interpolation").toElement();
622 if (!interpoationNode.isNull())
631 mInitialWindowWidth = width;
632 mInitialWindowLevel = level;
785 info->SetOutputExtentStart(0, 0, 0);
786 info->SetOutputOrigin(0, 0, 0);
788 info->UpdateInformation();
826 int size = axisSize - 1;
828 dummyImageData->SetExtent(0, size, 0, size, 0, size);
829 dummyImageData->SetSpacing(1, 1, 1);
834 dummyImageData->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
835 unsigned char* dataPtr =
static_cast<unsigned char*
> (dummyImageData->GetScalarPointer());
838 int minVoxelValue = 0;
839 int numVoxels = axisSize*axisSize*axisSize;
840 for (
int i = 0; i < numVoxels; ++i)
842 int voxelValue = minVoxelValue + i;
844 dataPtr[i] = maxVoxelValue;
845 else if (voxelValue < maxVoxelValue)
846 dataPtr[i] = voxelValue;
848 dataPtr[i] = maxVoxelValue;
851 return dummyImageData;
877 double factor = computeResampleFactor(maxVoxels);
879 if (fabs(1.0-factor)>0.01)
882 resampler->SetInterpolationModeToLinear();
883 resampler->SetAxisMagnificationFactor(0, factor);
884 resampler->SetAxisMagnificationFactor(1, factor);
885 resampler->SetAxisMagnificationFactor(2, factor);
886 resampler->SetInputData(retval);
889 resampler->GetOutput()->GetScalarRange();
890 retval = resampler->GetOutput();
892 long voxelsDown = retval->GetNumberOfPoints();
903 double Image::computeResampleFactor(
long maxVoxels)
909 double factor = (double)maxVoxels/(
double)voxels;
910 factor = pow(factor, 1.0/3.0);
922 QString filename = basePath +
"/Images/" + this->
getUid() +
".mhd";
923 this->
setFilename(QDir(basePath).relativeFilePath(filename));
virtual void parseXml(QDomNode &dataNode)
Use a XML node to load data.
QString qstring_cast(const T &val)
static vtkImageDataPtr createDummyImageData(int axisSize, int maxVoxelValue)
Create a moc object of vtkImageData.
Image(const QString &uid, const vtkImageDataPtr &data, const QString &name="")
virtual bool getCropping() const
virtual void setModality(const QString &val)
virtual Transform3D get_rMd() const
bool mUseCropping
image should be cropped using mCroppingBox
virtual vtkImageDataPtr getGrayScaleVtkImageData()
as getBaseVtkImageData(), but constrained to 1 component if multicolor.
int getInterpolationType() const
virtual Eigen::Array3d getSpacing() const
QString mImageType
type of the image, defined as DICOM tag (0008,0008) (mainly value 3, but might be a merge of value 4)...
void parseXml(QDomNode dataNode)
virtual void setTransferFunctions3D(ImageTF3DPtr transferFuntion)
PlainObject normal() const
virtual double getShadingDiffuse()
Get shading diffuse parmeter.
virtual vtkImageAccumulatePtr getHistogram()
void mergevtkSettingsIntosscTransform()
static ImagePtr create(const QString &uid, const QString &name)
void addXml(QDomNode dataNode)
#define CX_ASSERT(statement)
virtual void setShadingDiffuse(double diffuse)
Set shading diffuse parmeter.
virtual QString getModality() const
virtual std::vector< vtkPlanePtr > getAllClipPlanes()
virtual void addPersistentClipPlane(vtkPlanePtr plane)
virtual void setVtkImageData(const vtkImageDataPtr &data, bool resetTransferFunctions=true)
vtkSmartPointer< class vtkImageAccumulate > vtkImageAccumulatePtr
void propertiesChanged()
emitted when one of the metadata properties (uid, name etc) changes
virtual void setLookupTable2D(ImageLUT2DPtr imageLookupTable2D)
boost::shared_ptr< class Image > ImagePtr
virtual void setInitialWindowLevel(double width, double level)
vtkSmartPointer< vtkImageChangeInformation > vtkImageChangeInformationPtr
static DoubleBoundingBox3D fromString(const QString &text)
construct a bb from a string containing 6 whitespace-separated numbers
virtual void setCropping(bool on)
virtual Image::ShadingStruct getShading()
virtual void setShadingOn(bool on)
DoubleBoundingBox3D mCroppingBox_d
box defining the cropping size.
virtual void setShadingAmbient(double ambient)
Set shading ambient parmeter.
virtual vtkImageDataPtr getBaseVtkImageData()
static ImagePtr create(ImagePtr base)
virtual void addXml(QDomNode &dataNode)
adds xml information about the data and its variabels
virtual double getShadingSpecular()
Get shading specular parmeter.
virtual void setShadingSpecular(double specular)
Set shading specular parmeter.
virtual void setImageType(const QString &val)
ImagePtr mUnsigned
version of this containing unsigned data.
virtual ImagePtr getUnsigned(ImagePtr self)
virtual void intitializeFromParentImage(ImagePtr parentImage)
virtual QString getUid() const
bool similar(const DoubleBoundingBox3D &a, const DoubleBoundingBox3D &b, double tol)
virtual ImageTF3DPtr getTransferFunctions3D()
void addXml(QDomNode &dataNode)
adds xml information about the image and its variabels
virtual RegistrationHistoryPtr get_rMd_History()
vtkSmartPointer< class vtkImageChangeInformation > vtkImageChangeInformationPtr
boost::shared_ptr< class ImageLUT2D > ImageLUT2DPtr
ImageLUT2DPtr generate2DTFPreset()
vtkPlanePtr mInteractiveClipPlane
QString mModality
modality of the image, defined as DICOM tag (0008,0060), Section 3, C.7.3.1.1.1
void reportWarning(QString msg)
virtual int getMaxAlphaValue()
Max alpha value (probably 255)
vtkImageDataPtr convertImageDataTo8Bit(vtkImageDataPtr image, double windowWidth, double windowLevel)
Have never been used or tested. Create a test for it.
virtual void parseXml(QDomNode &dataNode)
Use a XML node to load data.
virtual void setShadingSpecularPower(double specularPower)
Set shading specular power parmeter.
void moveThisAndChildrenToThread(QThread *thread)
Move this and all children to thread. Use the thread is generated in a worker thread and the result i...
virtual int getRange()
For convenience: getMax() - getMin()
virtual void save(const QString &basePath)
void setAcquisitionTime(QDateTime time)
void transferFunctionsChanged()
emitted when image transfer functions in 2D or 3D are changed.
Transform3D createTransformTranslate(const Vector3D &translation)
Representation of an integer bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
Representation of a floating-point bounding box in 3D. The data are stored as {xmin,xmax,ymin,ymax,zmin,zmax}, in order to simplify communication with vtk.
vtkSmartPointer< class vtkImageResample > vtkImageResamplePtr
vtkImageAccumulatePtr mHistogramPtr
Histogram.
vtkImageDataPtr resample(long maxVoxels)
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Vector3D multiply_elems(const Vector3D &a, const Vector3D &b)
perform element-wise multiplication of a and b.
virtual void setInteractiveClipPlane(vtkPlanePtr plane)
set a plane that is not saved
virtual void setShading(Image::ShadingStruct shading)
vtkImageDataPtr convertImageDataToGrayScale(vtkImageDataPtr image)
RegistrationHistoryPtr m_rMd_History
Superclass for all data objects.
void setDeepModified(vtkImageDataPtr image)
void readInto(DataPtr data, QString path)
virtual DoubleBoundingBox3D getCroppingBox() const
std::vector< vtkPlanePtr > mPersistentClipPlanes
virtual void setCroppingBox(const DoubleBoundingBox3D &bb_d)
ImageTF3DPtr generate3DTFPreset()
void vtkImageDataChanged()
emitted when the vktimagedata are invalidated and must be retrieved anew.
virtual vtkImageDataPtr get8bitGrayScaleVtkImageData()
Have never been used or tested. Create a test for it.
REGISTRATION_STATUS mRegistrationStatus
virtual double getShadingAmbient()
Get shading ambient parmeter.
virtual bool load(QString path)
void setInterpolationType(int val)
virtual QString getImageType() const
void setInterpolationTypeToNearest()
virtual double getShadingSpecularPower()
Get shading specular power parmeter.
vtkImageDataPtr mBaseImageData
image data in data space
int mInterpolationType
mirror the interpolationType in vtkVolumeProperty
vtkSmartPointer< class vtkPlane > vtkPlanePtr
void setInterpolationTypeToLinear()
virtual void clearPersistentClipPlanes()
boost::shared_ptr< class ImageTF3D > ImageTF3DPtr
virtual void setFilename(QString val)
virtual void transformChangedSlot()
virtual ImageLUT2DPtr getLookupTable2D()
virtual bool getShadingOn() const
void resetTransferFunctions(bool _2D=true, bool _3D=true)
Resets the transfer functions and creates new defaut values.
virtual DoubleBoundingBox3D boundingBox() const
bounding box in image space
vtkImageDataPtr mBaseGrayScaleImageData
image data in data space