15 #include <QDomDocument> 17 #include <vtkImageAccumulate.h> 18 #include <vtkImageReslice.h> 19 #include <vtkImageData.h> 20 #include <vtkMatrix4x4.h> 22 #include <vtkPlanes.h> 23 #include <vtkImageResample.h> 24 #include <vtkImageChangeInformation.h> 25 #include <vtkImageClip.h> 26 #include <vtkImageIterator.h> 27 #include <vtkPiecewiseFunction.h> 28 #include <vtkColorTransferFunction.h> 60 double Image::ShadingStruct::loadAttribute(QDomNode dataNode, QString name,
double defVal)
62 QString text = dataNode.toElement().attribute(name);
64 double val = text.toDouble(&ok);
72 QDomElement elem = dataNode.toElement();
73 elem.setAttribute(
"on",
on);
74 elem.setAttribute(
"ambient",
ambient);
75 elem.setAttribute(
"diffuse",
diffuse);
76 elem.setAttribute(
"specular",
specular);
82 if (dataNode.isNull())
85 on = dataNode.toElement().attribute(
"on").toInt();
109 mInitialWindowWidth = -1;
110 mInitialWindowLevel = -1;
117 mImageLookupTable2D.reset();
118 mImageTransferFunctions3D.reset();
128 baseImageDataCopy = vtkImageDataPtr::New();
139 retval->mImageLookupTable2D = mImageLookupTable2D;
140 retval->mImageTransferFunctions3D = mImageTransferFunctions3D;
141 retval->mInitialWindowWidth = mInitialWindowWidth;
142 retval->mInitialWindowLevel = mInitialWindowLevel;
155 ImageTF3DPtr transferFunctions = parentImage->getUnmodifiedTransferFunctions3D()->createCopy();
156 ImageLUT2DPtr LUT2D = parentImage->getUnmodifiedLookupTable2D()->createCopy();
162 mInitialWindowWidth = parentImage->getInitialWindowWidth();
163 mInitialWindowLevel = parentImage->getInitialWindowLevel();
212 this->blockSignals(
true);
214 this->resetTransferFunction(imageTransferFunctions3D);
215 this->resetTransferFunction(imageLookupTable2D);
217 this->blockSignals(
false);
221 void Image::resetTransferFunction(
ImageLUT2DPtr imageLookupTable2D)
223 if (mImageLookupTable2D)
228 mImageLookupTable2D = imageLookupTable2D;
230 if (mImageLookupTable2D)
238 void Image::resetTransferFunction(
ImageTF3DPtr imageTransferFunctions3D)
240 if (mImageTransferFunctions3D)
245 mImageTransferFunctions3D = imageTransferFunctions3D;
247 if (mImageTransferFunctions3D)
262 this->moveToThread(thread);
263 this->getUnmodifiedTransferFunctions3D()->moveToThread(thread);
264 this->getUnmodifiedLookupTable2D()->moveToThread(thread);
274 if (resetTransferFunctions)
281 double windowWidth = this->getUnmodifiedLookupTable2D()->getWindow();
282 double windowLevel = this->getUnmodifiedLookupTable2D()->getLevel();
299 if(mThresholdPreview)
300 return mTresholdPreviewTransferfunctions3D;
301 return getUnmodifiedTransferFunctions3D();
306 if(!this->mImageTransferFunctions3D)
308 return mImageTransferFunctions3D;
313 this->resetTransferFunction(transferFuntion);
318 if(mThresholdPreview)
319 return mTresholdPreviewLookupTable2D;
320 return getUnmodifiedLookupTable2D();
325 if(!mImageLookupTable2D)
327 return mImageLookupTable2D;
332 this->resetTransferFunction(imageLookupTable2D);
368 template<
typename scalartype>
static int getRGBMax(
vtkImageDataPtr image)
371 vtkImageIterator<scalartype> iter(image, image->GetExtent());
372 while (!iter.IsAtEnd())
374 typename vtkImageIterator<scalartype>::SpanIterator siter = iter.BeginSpan();
375 while (siter != iter.EndSpan())
409 case VTK_UNSIGNED_CHAR:
412 case VTK_UNSIGNED_SHORT:
452 if (vtkScalarType==VTK_CHAR)
454 else if (vtkScalarType==VTK_UNSIGNED_CHAR)
455 return VTK_UNSIGNED_CHAR_MIN;
456 else if (vtkScalarType==VTK_SIGNED_CHAR)
457 return VTK_SIGNED_CHAR_MIN;
458 else if (vtkScalarType==VTK_UNSIGNED_SHORT)
459 return VTK_UNSIGNED_SHORT_MIN;
460 else if (vtkScalarType==VTK_SHORT)
461 return VTK_SHORT_MIN;
462 else if (vtkScalarType==VTK_UNSIGNED_INT)
463 return VTK_UNSIGNED_INT_MIN;
464 else if (vtkScalarType==VTK_INT)
466 else if (vtkScalarType==VTK_FLOAT)
467 return VTK_FLOAT_MIN;
469 reportError(QString(
"Unknown VTK ScalarType: %1").arg(vtkScalarType));
477 if (vtkScalarType==VTK_CHAR)
479 else if (vtkScalarType==VTK_UNSIGNED_CHAR)
480 return VTK_UNSIGNED_CHAR_MAX;
481 else if (vtkScalarType==VTK_SIGNED_CHAR)
482 return VTK_SIGNED_CHAR_MAX;
483 else if (vtkScalarType==VTK_UNSIGNED_SHORT)
484 return VTK_UNSIGNED_SHORT_MAX;
485 else if (vtkScalarType==VTK_SHORT)
486 return VTK_SHORT_MAX;
487 else if (vtkScalarType==VTK_UNSIGNED_INT)
488 return VTK_UNSIGNED_INT_MAX;
489 else if (vtkScalarType==VTK_INT)
491 else if (vtkScalarType==VTK_FLOAT)
492 return VTK_FLOAT_MAX;
494 reportError(QString(
"Unknown VTK ScalarType: %1").arg(vtkScalarType));
505 mDicomSeriesNumber = seriesNumber;
510 return mDicomSeriesNumber;
516 QDomNode imageNode = dataNode;
517 QDomDocument doc = dataNode.ownerDocument();
519 QDomElement tf3DNode = doc.createElement(
"transferfunctions");
520 this->getUnmodifiedTransferFunctions3D()->addXml(tf3DNode);
521 imageNode.appendChild(tf3DNode);
523 QDomElement lut2DNode = doc.createElement(
"lookuptable2D");
524 this->getUnmodifiedLookupTable2D()->addXml(lut2DNode);
525 imageNode.appendChild(lut2DNode);
527 QDomElement shadingNode = doc.createElement(
"shading");
529 imageNode.appendChild(shadingNode);
535 QDomElement cropNode = doc.createElement(
"crop");
538 imageNode.appendChild(cropNode);
540 QDomElement clipNode = doc.createElement(
"clip");
543 QDomElement planeNode = doc.createElement(
"plane");
548 clipNode.appendChild(planeNode);
550 imageNode.appendChild(clipNode);
552 QDomElement modalityNode = doc.createElement(
"modality");
554 imageNode.appendChild(modalityNode);
556 QDomElement imageTypeNode = doc.createElement(
"imageType");
558 imageNode.appendChild(imageTypeNode);
560 QDomElement interpolationNode = doc.createElement(
"vtk_interpolation");
562 imageNode.appendChild(interpolationNode);
564 QDomElement initialWindowNode = doc.createElement(
"initialWindow");
565 initialWindowNode.setAttribute(
"width", mInitialWindowWidth);
566 initialWindowNode.setAttribute(
"level", mInitialWindowLevel);
567 imageNode.appendChild(initialWindowNode);
570 double Image::loadAttribute(QDomNode dataNode, QString name,
double defVal)
572 QString text = dataNode.toElement().attribute(name);
574 double val = text.toDouble(&ok);
583 filemanager->readInto(
self, path);
594 if (dataNode.isNull())
598 QDomNode transferfunctionsNode = dataNode.namedItem(
"transferfunctions");
599 if (!transferfunctionsNode.isNull())
600 this->getUnmodifiedTransferFunctions3D()->parseXml(transferfunctionsNode);
603 std::cout <<
"Warning: Image::parseXml() found no transferfunctions";
604 std::cout << std::endl;
607 mInitialWindowWidth = this->loadAttribute(dataNode.namedItem(
"initialWindow"),
"width", mInitialWindowWidth);
608 mInitialWindowLevel = this->loadAttribute(dataNode.namedItem(
"initialWindow"),
"level", mInitialWindowLevel);
610 this->getUnmodifiedLookupTable2D()->parseXml(dataNode.namedItem(
"lookuptable2D"));
613 mShading.
on = dataNode.namedItem(
"shading").toElement().text().toInt();
615 if (!dataNode.namedItem(
"shadingAmbient").isNull())
616 mShading.
ambient = dataNode.namedItem(
"shadingAmbient").toElement().text().toDouble();
617 if (!dataNode.namedItem(
"shadingDiffuse").isNull())
618 mShading.
diffuse = dataNode.namedItem(
"shadingDiffuse").toElement().text().toDouble();
619 if (!dataNode.namedItem(
"shadingSpecular").isNull())
620 mShading.
specular = dataNode.namedItem(
"shadingSpecular").toElement().text().toDouble();
621 if (!dataNode.namedItem(
"shadingSpecularPower").isNull())
629 QDomElement cropNode = dataNode.namedItem(
"crop").toElement();
630 if (!cropNode.isNull())
636 QDomElement clipNode = dataNode.namedItem(
"clip").toElement();
637 QDomElement clipPlaneNode = clipNode.firstChildElement(
"plane");
638 for (; !clipPlaneNode.isNull(); clipPlaneNode = clipPlaneNode.nextSiblingElement(
"plane"))
640 Vector3D normal = Vector3D::fromString(clipPlaneNode.attribute(
"normal"));
641 Vector3D origin = Vector3D::fromString(clipPlaneNode.attribute(
"origin"));
643 plane->SetNormal(normal.begin());
644 plane->SetOrigin(origin.begin());
651 QDomElement interpoationNode = dataNode.namedItem(
"vtk_interpolation").toElement();
652 if (!interpoationNode.isNull())
661 mInitialWindowWidth = width;
662 mInitialWindowLevel = level;
673 if (mThresholdPreview)
788 info->SetOutputExtentStart(0, 0, 0);
789 info->SetOutputOrigin(0, 0, 0);
791 info->UpdateInformation();
829 int size = axisSize - 1;
831 dummyImageData->SetExtent(0, size, 0, size, 0, size);
832 dummyImageData->SetSpacing(1, 1, 1);
837 dummyImageData->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
838 unsigned char* dataPtr =
static_cast<unsigned char*
> (dummyImageData->GetScalarPointer());
841 int minVoxelValue = 0;
842 int numVoxels = axisSize*axisSize*axisSize;
843 for (
int i = 0; i < numVoxels; ++i)
845 int voxelValue = minVoxelValue + i;
847 dataPtr[i] = maxVoxelValue;
848 else if (voxelValue < maxVoxelValue)
849 dataPtr[i] = voxelValue;
851 dataPtr[i] = maxVoxelValue;
854 return dummyImageData;
870 if (mThresholdPreview)
877 if (mThresholdPreview)
878 return VTK_NEAREST_INTERPOLATION;
887 double factor = computeResampleFactor(maxVoxels);
889 if (fabs(1.0-factor)>0.01)
892 resampler->SetInterpolationModeToLinear();
893 resampler->SetAxisMagnificationFactor(0, factor);
894 resampler->SetAxisMagnificationFactor(1, factor);
895 resampler->SetAxisMagnificationFactor(2, factor);
896 resampler->SetInputData(retval);
899 resampler->GetOutput()->GetScalarRange();
900 retval = resampler->GetOutput();
913 double Image::computeResampleFactor(
long maxVoxels)
919 double factor = (double)maxVoxels/(
double)voxels;
920 factor = pow(factor, 1.0/3.0);
932 QString filename = basePath +
"/Images/" + this->
getUid() +
".mhd";
933 this->
setFilename(QDir(basePath).relativeFilePath(filename));
936 filemanager->save(
self, filename);
941 mThresholdPreview =
true;
943 this->createThresholdPreviewTransferFunctions3D(threshold);
944 this->createThresholdPreviewLookupTable2D(threshold);
949 void Image::createThresholdPreviewTransferFunctions3D(
const Eigen::Vector2d &threshold)
953 ColorMap colors = this->createPreviewColorMap(threshold);
954 IntIntMap opacity = this->createPreviewOpacityMap(threshold);
957 mTresholdPreviewTransferfunctions3D->resetColor(colors);
958 mTresholdPreviewTransferfunctions3D->resetAlpha(opacity);
961 void Image::createThresholdPreviewLookupTable2D(
const Eigen::Vector2d &threshold)
965 ColorMap colors = this->createPreviewColorMap(threshold);
968 mTresholdPreviewLookupTable2D->resetColor(colors);
969 mTresholdPreviewLookupTable2D->setLLR(threshold[0]);
972 ColorMap Image::createPreviewColorMap(
const Eigen::Vector2d &threshold)
974 double lower = threshold[0];
976 colors[lower] = Qt::green;
977 colors[this->
getMax()] = Qt::green;
981 IntIntMap Image::createPreviewOpacityMap(
const Eigen::Vector2d &threshold)
983 double lower = threshold[0];
984 double upper = threshold[1];
986 opacity[lower - 1] = 0;
989 opacity[upper + 1] = 0;
995 mThresholdPreview =
false;
996 mTresholdPreviewTransferfunctions3D.reset();
997 mTresholdPreviewLookupTable2D.reset();
virtual void parseXml(QDomNode &dataNode)
Use a XML node to load data.
QString qstring_cast(const T &val)
void transferFunctionsChanged()
static vtkImageDataPtr createDummyImageData(int axisSize, int maxVoxelValue)
Create a moc object of vtkImageData.
Image(const QString &uid, const vtkImageDataPtr &data, const QString &name="")
boost::shared_ptr< class FileManagerService > FileManagerServicePtr
virtual bool getCropping() const
void reportError(QString msg)
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
void parseXml(QDomNode dataNode)
virtual void setTransferFunctions3D(ImageTF3DPtr transferFuntion)
PlainObject normal() const
IMAGE_MODALITY mModality
modality of the image, defined as DICOM tag (0008,0060), Section 3, C.7.3.1.1.1
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 IMAGE_MODALITY getModality() const
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
IMAGE_MODALITY convertToModality(QString modalityString)
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.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
virtual void setShadingAmbient(double ambient)
Set shading ambient parmeter.
virtual vtkImageDataPtr getBaseVtkImageData()
static ImagePtr create(ImagePtr base)
virtual void setModality(const IMAGE_MODALITY &val)
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.
ImagePtr mUnsigned
version of this containing unsigned data.
virtual ImagePtr getUnsigned(ImagePtr self)
virtual void save(const QString &basePath, FileManagerServicePtr filemanager)
virtual void intitializeFromParentImage(ImagePtr parentImage)
virtual QString getUid() const
virtual ImageTF3DPtr getTransferFunctions3D()
void addXml(QDomNode &dataNode)
adds xml information about the image and its variabels
virtual RegistrationHistoryPtr get_rMd_History()
std::map< int, QColor > ColorMap
IMAGE_SUBTYPE mImageType
type of the image, defined as DICOM tag (0008,0008) (mainly value 3, but might be a merge of value 4)...
virtual void setImageType(const IMAGE_SUBTYPE &val)
boost::shared_ptr< class ImageLUT2D > ImageLUT2DPtr
QString getDicomSeriesNumber()
ImageLUT2DPtr generate2DTFPreset()
void startThresholdPreview(const Eigen::Vector2d &threshold)
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 bool load(QString path, FileManagerServicePtr filemanager)
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...
IMAGE_SUBTYPE convertToImageSubType(QString imageTypeSubString)
virtual int getRange()
For convenience: getMax() - getMin()
void setAcquisitionTime(QDateTime time)
void transferFunctionsChanged()
emitted when image transfer functions in 2D or 3D are changed.
Transform3D createTransformTranslate(const Vector3D &translation)
Settings * settings()
Shortcut for accessing the settings instance.
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 setShading(Image::ShadingStruct shading)
vtkImageDataPtr convertImageDataToGrayScale(vtkImageDataPtr image)
RegistrationHistoryPtr m_rMd_History
Superclass for all data objects.
std::map< int, int > IntIntMap
void setDeepModified(vtkImageDataPtr image)
void vtkImageDataChanged(QString uid=QString())
emitted when the vktimagedata are invalidated and must be retrieved anew.
virtual DoubleBoundingBox3D getCroppingBox() const
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
virtual void setCroppingBox(const DoubleBoundingBox3D &bb_d)
ImageTF3DPtr generate3DTFPreset()
virtual vtkImageDataPtr get8bitGrayScaleVtkImageData()
Have never been used or tested. Create a test for it.
REGISTRATION_STATUS mRegistrationStatus
virtual double getShadingAmbient()
Get shading ambient parmeter.
void stopThresholdPreview()
void setInterpolationType(int val)
virtual double getShadingSpecularPower()
Get shading specular power parmeter.
virtual IMAGE_SUBTYPE getImageType() const
void setDicomSeriesNumber(QString seriesNumber)
vtkImageDataPtr mBaseImageData
image data in data space
int mInterpolationType
mirror the interpolationType in vtkVolumeProperty
vtkSmartPointer< class vtkPlane > vtkPlanePtr
QString enum2string(const ENUM &val)
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 default values.
virtual DoubleBoundingBox3D boundingBox() const
bounding box in image space
Namespace for all CustusX production code.
std::vector< vtkPlanePtr > mPersistentClipPlanes
vtkImageDataPtr mBaseGrayScaleImageData
image data in data space