471 lines
13 KiB
C++
471 lines
13 KiB
C++
|
|
/*
|
|
|
|
Calculate Ditigally Reconstructed Topogram from a CT dataset using a modified
|
|
version of incremental ray-tracing algorithm
|
|
|
|
gfattori 08.11.2021
|
|
|
|
*/
|
|
|
|
|
|
#ifndef ITKIMAGEPROCESSOR_H
|
|
#define ITKIMAGEPROCESSOR_H
|
|
|
|
|
|
#include "DRTMetaInformation.h"
|
|
|
|
#include "itkCommand.h"
|
|
|
|
#include "itkgSiddonJacobsRayCastInterpolateImageFunction.h"
|
|
#include "itkEuler3DTransform.h"
|
|
#include "itkResampleImageFilter.h"
|
|
#include "itkCastImageFilter.h"
|
|
#include "itkRescaleIntensityImageFilter.h"
|
|
#include "itkIntensityWindowingImageFilter.h"
|
|
#include "itkChangeInformationImageFilter.h"
|
|
#include "itkGDCMImageIO.h"
|
|
#include "itkMetaDataObject.h"
|
|
#include "itkImageDuplicator.h"
|
|
#include "itkObject.h"
|
|
#include "itkObjectFactory.h"
|
|
#include "itkSmartPointer.h"
|
|
|
|
#include "itkImageToVTKImageFilter.h"
|
|
|
|
#include "itkImageFileReader.h"
|
|
#include "itkImageFileWriter.h"
|
|
#include "itkImageSeriesReader.h"
|
|
|
|
#include "gdcmGlobal.h"
|
|
|
|
#include "vtkImageData.h"
|
|
#include "vtkTransform.h"
|
|
#include "vtkSmartPointer.h"
|
|
|
|
#include "itkQtIterationUpdate.h"
|
|
|
|
#include "itkImageProcessorHelpers.h"
|
|
|
|
#include "itkReg23.h"
|
|
#include "itkReg23MetaInformation.h"
|
|
|
|
#define IMG_VIS_MAXIMUM_RANGE 2048
|
|
|
|
namespace itk
|
|
{
|
|
|
|
class ITK_EXPORT itkImageProcessor : public itk::Object
|
|
{
|
|
|
|
constexpr static unsigned int Dimension = 3;
|
|
|
|
public:
|
|
/** Standard "Self" typedef. */
|
|
typedef itkImageProcessor Self;
|
|
/** Standard "Superclass" typedef. */
|
|
typedef Object Superclass;
|
|
/** Smart pointer typedef support */
|
|
typedef itk::SmartPointer<Self> Pointer;
|
|
typedef itk::SmartPointer<const Self> ConstPointer;
|
|
/** Method of creation through the object factory. */
|
|
itkNewMacro(Self);
|
|
/** Run-time type information (and related methods). */
|
|
itkTypeMacro(itkImageProcessor, Object);
|
|
|
|
|
|
itkSetMacro(ResamplepCT, bool);
|
|
itkGetMacro(ResamplepCT, bool);
|
|
|
|
itkSetMacro(SamplingLNG, double);
|
|
itkGetMacro(SamplingLNG, double);
|
|
|
|
CommandIterationUpdate::Pointer
|
|
optimizerObserver;
|
|
|
|
ExhaustiveCommandIterationUpdate::Pointer
|
|
ExhaustiveOptimizerObserver;
|
|
|
|
/** Sets the degree of freedom for optimzation*/
|
|
tDegreeOfFreedomEnum GetDegreeOfFreedom();
|
|
/** Returns user components only of the autoReg
|
|
* */
|
|
Optimizer::ParametersType
|
|
GetFinalR23Parameters();
|
|
/** Define the region to be used as ROI on fixed images */
|
|
void SetRegionFixed1(int,int,int,int);
|
|
void SetRegionFixed2(int,int,int,int);
|
|
void ResetROIRegions();
|
|
void InizializeRegistration();
|
|
|
|
/** Maximum number of iterations for the optimizer */
|
|
itkGetMacro(R23, itkReg23::Pointer);
|
|
|
|
|
|
/** Set Optimizer type */
|
|
void SetOptimizer(std::string);
|
|
void SetOptimizer(tOptimizerTypeEnum);
|
|
|
|
/** Set Metric type */
|
|
void SetMetric(std::string);
|
|
void SetMetric(tMetricTypeEnum);
|
|
|
|
/** Set DOF */
|
|
void SetDegreeOfFreedom(tDegreeOfFreedomEnum);
|
|
|
|
/** Set Handle Of Rotation Import Offset */
|
|
void SetHandleRotationImportOffset(tHandlingRotImpTransform);
|
|
|
|
/** Set PowellOptimizer */
|
|
void SetPowellOptimParameters(double,double,double,int,int);
|
|
|
|
/** Set AmoebaOptimizer */
|
|
void SetAmoebaOptimParameters(double,double,double,int);
|
|
|
|
/** Set MI */
|
|
void SetMIMetricParameters(double,int);
|
|
|
|
/** Set NCC */
|
|
void SetNCCMetricParameters(double,bool);
|
|
|
|
/** Set number of logic CPU to be made available to interpolators*/
|
|
void SetNumberOfWorkingUnits(int iN);
|
|
|
|
/** Input data load methods*/
|
|
int load3DSerieFromFiles( std::vector<std::string> );
|
|
int unload3DVolumeAndMeta();
|
|
|
|
int load2D(const char *);
|
|
int unload2DAndMeta(int);
|
|
//int query2DimageReconstructionDiameter(const char*);
|
|
|
|
void loadRTPlanInfo(double, double, double, double, double ,double);
|
|
int unloadRTPlanAndMeta();
|
|
|
|
/** Projection angles - Gantry angle IEC */
|
|
void SetProjectionAngle1IEC(double);
|
|
void SetProjectionAngle2IEC(double);
|
|
void SetProjectionAngleOffsetIEC(double,double);
|
|
/** Get projection angles - Gantry angle LPS
|
|
* Only meaningful after a 3D Volume is loaded */
|
|
double GetProjectionAngle1LPS();
|
|
double GetProjectionAngle2LPS();
|
|
|
|
/** Source to axis distance - SAD
|
|
* Often called source to object (SOD), (0018,1111) */
|
|
void SetSCD(double,double);
|
|
void SetSCDOffset(double,double);
|
|
|
|
double GetSCD1();
|
|
double GetSCD2();
|
|
|
|
/** Panel offsets - panel offsets IEC */
|
|
void SetPanelOffsets(double,double);
|
|
|
|
/** Panel offsets - takes into account patient orientation */
|
|
double GetPanelOffsetPGeo(tProjOrientationType ImgPrj);
|
|
|
|
/** Get projection angles - Gantry angle LPS
|
|
* Only meaningful after a 3D Volume is loaded */
|
|
double GetPanelOffset1();
|
|
double GetPanelOffset2();
|
|
|
|
void SetCustom_ProjectionCenterOffsetFixedAxes_IEC(double,double,double,double,double,double);
|
|
void SetCustom_ProjectionCenterFixedAxes_IEC(double,double,double);
|
|
|
|
/** Intensity threshold used for image projection,
|
|
* any voxel below threshold is ignored */
|
|
void SetIntensityThreshold(double);
|
|
|
|
/** Custom settings of the projection images */
|
|
void SetCustom_2Dres(double,double,double,double);
|
|
void SetCustom_2Dsize(int,int,int,int);
|
|
|
|
/** Custom transform to map IEC of imaging device into IEC-Support
|
|
* Tx Ty Tz [mm] Rx Ry Rz [deg]
|
|
*/
|
|
void SetCustom_ImportTransform(double, double, double,
|
|
double, double, double);
|
|
|
|
/** Should rotations be used when computing import offset and hidden transform? */
|
|
void SetUseRotationsForImportOffset(bool bVal);
|
|
|
|
void SetCustom_UpdateMetaInfo();
|
|
|
|
|
|
/** Set transform parameters for 3D Volume */
|
|
void SetInitialTranslations(double, double, double);
|
|
void SetInitialRotations(double, double, double);
|
|
|
|
///** Get transform parameters for 3D Volume */
|
|
/** Get the complete transform, likely for export to SRO.
|
|
* This includes user and hidden contributions.
|
|
* Transform center has to be specified, Zero would result
|
|
* in Isocentric transform with center at the RT Iso.
|
|
*/
|
|
TransformType::Pointer
|
|
GetCompleteIsocentricTransform(/*ImageType3D::PointType TransformCenter*/);
|
|
|
|
/** Get only the User component of the transform
|
|
* as parameters' list. Import offset and hidden not included.
|
|
* This can be use to update UI transform display
|
|
* ParametersType :: Rx Ry Rz Tx Ty Tz
|
|
*/
|
|
Optimizer::ParametersType
|
|
GetUserIsocentricTransform();
|
|
|
|
/** Return useful meta info for external use
|
|
* Consumer should check for nullptr...
|
|
*/
|
|
const CTVolumeImageMetaInformation::Pointer
|
|
GetCTMetaInfo();
|
|
const RTGeometryMetaInformation::Pointer
|
|
GetRTMetaInfo();
|
|
const DRTProjectionGeometryImageMetaInformation::Pointer
|
|
GetDRTGeoMetaInfo();
|
|
|
|
/** Initialize projection geometry */
|
|
void InitializeProjector();
|
|
|
|
/** Get Projection origin in LPS coordinates*/
|
|
const std::vector <double> GetLPStoProjectionGeoLPSOffset();
|
|
|
|
/** Get Projection origin in LPS coordinates*/
|
|
const std::vector <double> GetRTImportOffset();
|
|
|
|
/** Get the Localizer intensity window and
|
|
* center for rendering */
|
|
double GetLocalizerDisplayWindowLevel(int );
|
|
double GetLocalizerDisplayWindowWidth(int );
|
|
|
|
/** Compute Digital Localizers */
|
|
void GetProjectionImages();
|
|
|
|
/** Conveniency methods to get VTK images for rendering */
|
|
vtkImageData* GetProjection1VTK();
|
|
vtkImageData* GetProjection2VTK();
|
|
|
|
/** Conveniency methods to get VTK images for rendering */
|
|
vtkImageData* GetProjection1VTKToWrite();
|
|
vtkImageData* GetProjection2VTKToWrite();
|
|
|
|
vtkImageData* GetLocalizer1VTK();
|
|
vtkImageData* GetLocalizer2VTK();
|
|
|
|
vtkMatrix4x4 * GetProjection1VTKTransform();
|
|
vtkMatrix4x4 * GetProjection2VTKTransform();
|
|
|
|
/** Debug writers */
|
|
void WriteProjectionImages();
|
|
void Write2DImages();
|
|
|
|
|
|
protected:
|
|
/** Various pixel types */
|
|
using InternalPixelType = float;
|
|
using PixelType2D = short;
|
|
using PixelType3D = short;
|
|
using OutputPixelType = unsigned short;
|
|
|
|
using ImageType3D = itk::Image<PixelType3D, Dimension>;
|
|
using InternalImageType = itk::Image<InternalPixelType, Dimension>;
|
|
|
|
itkImageProcessor();
|
|
virtual ~itkImageProcessor();
|
|
void PrintSelf(std::ostream& os, itk::Indent indent) const;
|
|
|
|
bool
|
|
m_ResamplepCT;
|
|
double
|
|
m_SamplingLNG;
|
|
|
|
private:
|
|
itkImageProcessor(const Self&); //purposely not implemented
|
|
void operator=(const Self&); //purposely not implemented
|
|
|
|
/** Fill Meta after 3D volume load */
|
|
int fill3DVolumeMeta(InternalImageType::Pointer,
|
|
tPatOrientation);
|
|
|
|
/** Image types */
|
|
using ImageType2D = itk::Image<PixelType3D, Dimension>;
|
|
|
|
using OutputImageType = itk::Image<OutputPixelType, Dimension>;
|
|
|
|
/** The following lines define each of the components used in the
|
|
registration: The transform, optimizer, metric, interpolator and
|
|
the registration method itself. */
|
|
using InterpolatorType = itk::gSiddonJacobsRayCastInterpolateImageFunction<InternalImageType, double>;
|
|
using ResampleFilterType = itk::ResampleImageFilter<InternalImageType, InternalImageType>;
|
|
|
|
|
|
using RoiForRegistration = itk::ImageRegion<Dimension>;
|
|
|
|
/** Image reader types */
|
|
using ImageReaderType2D = itk::ImageFileReader<ImageType2D>;
|
|
using ImageReaderType3D = itk::ImageFileReader<ImageType3D>;
|
|
using ImageSeriesReaderType3D = itk::ImageSeriesReader<ImageType3D>;
|
|
using ImageIOType = itk::GDCMImageIO;
|
|
using DuplicatorType = itk::ImageDuplicator<InternalImageType>;
|
|
|
|
/** Image input resampling Types */
|
|
using ResampleInputFilterType = itk::ResampleImageFilter<ImageType3D, ImageType3D>;
|
|
using LinearInterpolatorType = itk::LinearInterpolateImageFunction<ImageType3D, double>;
|
|
using SizeValueType = ImageType3D::SizeType::SizeValueType;
|
|
|
|
/** widely used filters: flip, cast, rescale, ... */
|
|
using Input2DRescaleFilterType = itk::RescaleIntensityImageFilter<InternalImageType, InternalImageType>;
|
|
using CastFilterType3D = itk::CastImageFilter<ImageType3D, InternalImageType>;
|
|
using ChangeInformationFilterType = itk::ChangeInformationImageFilter<InternalImageType>;
|
|
using ChangeInformationFilterInput2DType = itk::ChangeInformationImageFilter<ImageType2D>;
|
|
|
|
/** ITK to VTK filter */
|
|
using ITKtoVTKFilterType = itk::ImageToVTKImageFilter<OutputImageType>;
|
|
|
|
TransformType::Pointer
|
|
transform1,
|
|
transform2,
|
|
IsocTransf;
|
|
|
|
InterpolatorType::Pointer
|
|
interpolator1,
|
|
interpolator2;
|
|
|
|
ITKtoVTKFilterType::Pointer
|
|
toVTK2D1,
|
|
toVTK2D2,
|
|
toVTKLocalizer1,
|
|
toVTKLocalizer2;
|
|
|
|
InternalImageType::Pointer
|
|
imageDRT1In,
|
|
imageDRT2In;
|
|
|
|
|
|
DuplicatorType::Pointer
|
|
m_LATSourceDupli,
|
|
m_PASourceDupli,
|
|
m_VolumeSourceDupli;
|
|
|
|
/** Apply transform to CT volume.
|
|
* This moves the volume based on RT Plan info
|
|
* if those are available. */
|
|
void UpdateProjectionGeometryMeta();
|
|
|
|
/* The following functions do not rely on class variables,
|
|
* Only input variables are used... */
|
|
|
|
InternalImageType::DirectionType
|
|
CalcDRTImageDirections(double angle,
|
|
InternalImageType::DirectionType DRT2LPS);
|
|
|
|
ImageType3D::PointType
|
|
CalcDRTImageOrigin(
|
|
ImageType3D::PointType m_DRTOrigin,
|
|
ImageType3D::PointType m_DRTCOV,
|
|
ImageType3D::PointType m_ProjectionCenterLPS,
|
|
double dAngle,
|
|
InternalImageType::DirectionType stdDRT2LPS
|
|
);
|
|
|
|
|
|
double
|
|
CalcProjectionAngleLPS(
|
|
tPatOrientation pOrient,
|
|
double pAngleIEC);
|
|
|
|
double
|
|
CalcPanelOffsetPGeo(
|
|
tPatOrientation pOrient,
|
|
double dPOffset);
|
|
/** Apply transform to CT volume.
|
|
* This moves the volume based on RT Plan info
|
|
* if those are available. */
|
|
ImageType3D::PointType
|
|
CalcImportVolumeOffset(
|
|
ImageType3D::PointType rtCouchOffset,
|
|
InternalImageType::DirectionType VolumeLPStoIEC,
|
|
ImageType3D::PointType rtIsocenterLPS,
|
|
ImageType3D::PointType IEC2DCMMapT,
|
|
ImageType3D::PointType IEC2DCMMapR);
|
|
|
|
|
|
// The ResampleImageFilter is the driving force for the projection image generation.
|
|
ResampleFilterType::Pointer
|
|
resampleFilter1,
|
|
resampleFilter2;
|
|
|
|
ChangeInformationFilterType::Pointer
|
|
filter1,
|
|
filter2;
|
|
|
|
InternalImageType::DirectionType
|
|
Std_DRT2LPS;
|
|
|
|
vtkMatrix4x4
|
|
* m_Projection1VTKTransform,
|
|
* m_Projection2VTKTransform;
|
|
|
|
/**
|
|
* Many meta containers
|
|
*/
|
|
CTVolumeImageMetaInformation::Pointer
|
|
m_CTMetaInfo;
|
|
|
|
DRTProjectionGeometryImageMetaInformation::Pointer
|
|
m_DRTGeometryMetaInfo;
|
|
|
|
DRTImageMetaInformation::Pointer
|
|
m_DRTImage1MetaInfo,
|
|
m_DRTImage2MetaInfo;
|
|
|
|
TopogramImageMetaInformation::Pointer
|
|
m_TImage1MetaInfo,
|
|
m_TImage2MetaInfo;
|
|
|
|
RTGeometryMetaInformation::Pointer
|
|
m_RTMetaInfo;
|
|
|
|
TransformMetaInformation::Pointer
|
|
m_TransformMetaInfo;
|
|
|
|
R23MetaInformation::Pointer
|
|
m_r23MetaInfo;
|
|
|
|
PowellOptimizerMetaInformation::Pointer
|
|
m_PowellOptimizerMetaInfo;
|
|
|
|
AmoebaOptimizerMetaInformation::Pointer
|
|
m_AmoebaOptimizerMetaInfo;
|
|
|
|
MIMetricMetaInformation::Pointer
|
|
m_MIMetricMetaInfo;
|
|
|
|
NCCMetricMetaInformation::Pointer
|
|
m_NCCMetricMetaInfo;
|
|
|
|
InternalTransformMetaInformation::Pointer
|
|
m_InternalTransf1,
|
|
m_InternalTransf2;
|
|
|
|
|
|
RoiForRegistration
|
|
roiAutoReg1,
|
|
roiAutoReg2;
|
|
|
|
|
|
int
|
|
iNWUnits;
|
|
|
|
|
|
itk::itkReg23::Pointer
|
|
m_R23;
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|