Rework of projection reference frame. Now we preserve patient LPS until the end and DRT can be directly overlay with Topogram with no further manipulation. Projeciton is in Patient Orientation.

Projection angle is set by user in IEC and corrected for patient orientation (HFS,FFS, ..) before internal use
Detection of Topogram projection (LAT or PA) is done on load, accounting for patient orientation and image direction cosines
This commit is contained in:
2022-02-07 18:00:22 +01:00
parent c196ae3dbb
commit d9e7d4fe6d
2 changed files with 570 additions and 470 deletions

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,7 @@ gfattori 08.11.2021
#include "itkNormalizedCorrelationTwoImageToOneImageMetric.h"
#include "itkGDCMImageIO.h"
#include "itkMetaDataObject.h"
#include "itkImageDuplicator.h"
#include "gdcmGlobal.h"
@ -80,6 +81,7 @@ public:
/* reference string required for comparison with tag values */
static const char *ImageOrientationStrings[] = {
"NotDefined",
"HFS",
"FFS"
};
@ -103,7 +105,7 @@ public:
itkTypeMacro(itkImageProcessor, Object);
/** Input data load methods*/
void load3DVolume(const char *);
//void load3DVolume(const char *);
int load3DSerie(const char* );
int load2D(const char *);
@ -150,34 +152,47 @@ public:
void WriteProjectionImages();
void Write2DImages();
/** Various pixel types */
using InternalPixelType = float;
using PixelType2D = short;
using PixelType3D = short;
using OutputPixelType = unsigned char;
using ImageType3D = itk::Image<PixelType3D, Dimension>;
using InternalImageType = itk::Image<InternalPixelType, Dimension>;
typedef enum eProjectionOrientationType
{NA = 0, LAT=2, PA=1}
tProjOrientationType;
/** Enum type for Orientation */
typedef enum eImageOrientationType
{ NotDefined = 0, HFS = 1, FFS = 2}
tPatOrientation;
protected:
itkImageProcessor();
virtual ~itkImageProcessor();
void PrintSelf(std::ostream& os, Indent indent) const;
private:
itkImageProcessor(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
void Finalize();
/** Various pixel types */
using InternalPixelType = float;
using PixelType2D = short;
using PixelType3D = short;
using OutputPixelType = unsigned char;
/** Image types */
using ImageType2D = itk::Image<PixelType3D, Dimension>;
using ImageType3D = 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 InternalImageType = itk::Image<InternalPixelType, Dimension>;
using TransformType = itk::Euler3DTransform<double>;
using OptimizerType = itk::PowellOptimizer;
using MetricType = itk::NormalizedCorrelationTwoImageToOneImageMetric<InternalImageType, InternalImageType>;
@ -190,6 +205,7 @@ private:
using ImageReaderType3D = itk::ImageFileReader<ImageType3D>;
using ImageSeriesReaderType3D = itk::ImageSeriesReader<ImageType3D>;
using ImageIOType = itk::GDCMImageIO;
using DuplicatorType = itk::ImageDuplicator<InternalImageType>;
/** widely used filters: flip, cast, rescale, ... */
using FlipFilterType = itk::FlipImageFilter<InternalImageType>;
@ -197,12 +213,12 @@ private:
using CastFilterType3D = itk::CastImageFilter<ImageType3D, InternalImageType>;
using ChangeInformationFilterType = itk::ChangeInformationImageFilter<InternalImageType>;
using ChangeInformationFilterInputType = itk::ChangeInformationImageFilter<ImageType3D>;
using ChangeInformationFilterInput2DType = itk::ChangeInformationImageFilter<ImageType2D>;
/** ITK to VTK filter */
using ITKtoVTKFilterType = itk::ImageToVTKImageFilter<OutputImageType>;
/** Enum type for Orientation */
enum eImageOrientationType { HFS = 0, FFS = 1};
MetricType::Pointer metric;
@ -212,7 +228,7 @@ private:
InterpolatorType::Pointer interpolator2;
RegistrationType::Pointer registration;
ImageReaderType2D::Pointer imageReader2D;
// ImageReaderType2D::Pointer imageReader2D;
ImageReaderType3D::Pointer imageReader3D;
ImageSeriesReaderType3D::Pointer imageSeriesReader3D;
@ -226,7 +242,7 @@ private:
CastFilterType3D::Pointer caster3D;
CastFilterType3D::Pointer caster2D1;
CastFilterType3D::Pointer caster2D2;
CastFilterType3D::Pointer caster2DInput;
TransformType::InputPointType isocenter3D;
@ -238,15 +254,33 @@ private:
ImageType3D::Pointer image3DIn;
InternalImageType::Pointer image2D1In;
InternalImageType::Pointer image2D2In;
ImageType2D::Pointer image2DInGeneric;
Input2DRescaleFilterType::Pointer image2D1Rescaler;
Input2DRescaleFilterType::Pointer image2D2Rescaler;
InternalImageType::Pointer TMPImg1;
InternalImageType::Pointer TMPImg2;
DuplicatorType::Pointer m_LATSourceDupli;
DuplicatorType::Pointer m_PASourceDupli;
ChangeInformationFilterInputType::Pointer image3DIECFilt;
tPatOrientation
m_3DPatOrientation;
InternalImageType::DirectionType
LPStoIEC_Directions;
InternalImageType::DirectionType
CalcDRTImageDirections(double angle);
ImageType3D::PointType
CalcDRTImageOrigin(InternalImageType::Pointer m_Image,
ImageType3D::PointType m_VolCOOV,
double dAngle
);
double
CalcProjectionAngleLPS(
tPatOrientation pOrient,
double pAngleIEC);
double image1res[2], image2res[2];
double image1center[2], image2center[2];
@ -255,6 +289,7 @@ private:
double scd;
double threshold;
double projAngle1, projAngle2;
double projAngle1_IEC, projAngle2_IEC;
double TZero[3], RZero[3];
double image3DCOV[3];
@ -264,6 +299,9 @@ private:
double image1IntensityWindow[2], image2IntensityWindow[2];
InternalImageType::DirectionType Std_DRT2LPS;
};