Files
reg23Topograms/itkReg23DRT/itkImageProcessor.h
2025-05-14 23:20:02 +02:00

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