First integration of Automatic Registration is running (on Approve button). There is in this commit soem confusion and changes in the DRR writing for testing with Alex
This commit is contained in:
@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 2.8.12)
|
|||||||
|
|
||||||
SET(LIB_NAME itkDTRrecon)
|
SET(LIB_NAME itkDTRrecon)
|
||||||
|
|
||||||
|
add_subdirectory(autoreg)
|
||||||
|
|
||||||
find_package(ITK REQUIRED)
|
find_package(ITK REQUIRED)
|
||||||
include(${ITK_USE_FILE})
|
include(${ITK_USE_FILE})
|
||||||
INCLUDE_DIRECTORIES(${ITK_INCLUDE_DIRS})
|
INCLUDE_DIRECTORIES(${ITK_INCLUDE_DIRS})
|
||||||
@ -34,6 +36,7 @@ SET(LINK_LIBS
|
|||||||
${VTK_LIBRARIES}
|
${VTK_LIBRARIES}
|
||||||
${ITK_LIBRARIES}
|
${ITK_LIBRARIES}
|
||||||
gdcmMSFF
|
gdcmMSFF
|
||||||
|
autoreg
|
||||||
)
|
)
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(
|
TARGET_LINK_LIBRARIES(
|
||||||
|
@ -531,6 +531,8 @@ TransformMetaInformation (){
|
|||||||
|
|
||||||
m_CurrentTransform.Fill(0.);
|
m_CurrentTransform.Fill(0.);
|
||||||
|
|
||||||
|
m_DegreeOfFreedom = tDegreeOfFreedomEnum::UNKNOWN;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -11,15 +11,70 @@
|
|||||||
namespace itk
|
namespace itk
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef enum eProjectionOrientationType
|
typedef enum eProjectionOrientationType{
|
||||||
{NA = 0, LAT=2, PA=1}
|
NA = 0,
|
||||||
tProjOrientationType;
|
LAT=2,
|
||||||
|
PA=1
|
||||||
|
} tProjOrientationType;
|
||||||
|
|
||||||
/** Enum type for Orientation */
|
/** Enum type for Orientation */
|
||||||
typedef enum eImageOrientationType
|
typedef enum eImageOrientationType{
|
||||||
{NotDefined = 0, HFS = 1, FFS = 2}
|
NotDefined = 0,
|
||||||
tPatOrientation;
|
HFS = 1,
|
||||||
|
FFS = 2
|
||||||
|
} tPatOrientation;
|
||||||
|
|
||||||
|
typedef enum eDegreeOfFreedomType {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
THREE_DOF,
|
||||||
|
SIX_DOF,
|
||||||
|
X_ONLY,
|
||||||
|
Y_ONLY,
|
||||||
|
Z_ONLY,
|
||||||
|
ROTATION_ONLY,
|
||||||
|
OTHER
|
||||||
|
} tDegreeOfFreedomEnum;
|
||||||
|
|
||||||
|
inline int GetNumberOfDOF(eDegreeOfFreedomType dof)
|
||||||
|
{
|
||||||
|
switch (dof) {
|
||||||
|
case SIX_DOF:
|
||||||
|
return 6;
|
||||||
|
break;
|
||||||
|
case THREE_DOF:
|
||||||
|
case ROTATION_ONLY:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
case X_ONLY:
|
||||||
|
case Y_ONLY:
|
||||||
|
case Z_ONLY:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DegreeOfFreedom : public itk::Object {
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef DegreeOfFreedom Self;
|
||||||
|
typedef itk::Object Superclass;
|
||||||
|
typedef itk::SmartPointer<Self> Pointer;
|
||||||
|
|
||||||
|
itkNewMacro(Self);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool
|
||||||
|
m_TranslationX,
|
||||||
|
m_TranslationY,
|
||||||
|
m_TranslationZ,
|
||||||
|
m_RotationX,
|
||||||
|
m_RotationY,
|
||||||
|
m_RotationZ;
|
||||||
|
tDegreeOfFreedomEnum m_dof;
|
||||||
|
};
|
||||||
|
|
||||||
class TopogramImageMetaInformation :
|
class TopogramImageMetaInformation :
|
||||||
public itk::Object{
|
public itk::Object{
|
||||||
@ -490,6 +545,8 @@ public:
|
|||||||
itkSetMacro(CurrentTransform,TransformMatrixType);
|
itkSetMacro(CurrentTransform,TransformMatrixType);
|
||||||
itkGetMacro(CurrentTransform,TransformMatrixType);
|
itkGetMacro(CurrentTransform,TransformMatrixType);
|
||||||
|
|
||||||
|
itkSetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum);
|
||||||
|
itkGetEnumMacro(DegreeOfFreedom, tDegreeOfFreedomEnum);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -503,6 +560,8 @@ protected:
|
|||||||
m_ReferenceTransform,
|
m_ReferenceTransform,
|
||||||
m_CurrentTransform;
|
m_CurrentTransform;
|
||||||
|
|
||||||
|
tDegreeOfFreedomEnum
|
||||||
|
m_DegreeOfFreedom;
|
||||||
|
|
||||||
/** Default Constructor **/
|
/** Default Constructor **/
|
||||||
TransformMetaInformation ();
|
TransformMetaInformation ();
|
||||||
|
@ -14,6 +14,7 @@ gfattori 08.11.2021
|
|||||||
#include "itkImageProcessor.h"
|
#include "itkImageProcessor.h"
|
||||||
|
|
||||||
#include "itkCreateObjectFunction.h"
|
#include "itkCreateObjectFunction.h"
|
||||||
|
#include "itkDRTHelpers.h"
|
||||||
#include "itkVersion.h"
|
#include "itkVersion.h"
|
||||||
#include <gdcmReader.h>
|
#include <gdcmReader.h>
|
||||||
#include <itkMatrix.h>
|
#include <itkMatrix.h>
|
||||||
@ -24,6 +25,8 @@ gfattori 08.11.2021
|
|||||||
#include "itkOrientImageFilter.h"
|
#include "itkOrientImageFilter.h"
|
||||||
#include <gdcmIPPSorter.h>
|
#include <gdcmIPPSorter.h>
|
||||||
|
|
||||||
|
#include "itkTimeProbesCollectorBase.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
@ -31,34 +34,6 @@ gfattori 08.11.2021
|
|||||||
namespace itk
|
namespace itk
|
||||||
{
|
{
|
||||||
|
|
||||||
/* this is in the end a IEC to HFS...
|
|
||||||
* but we keep this for ourselves...
|
|
||||||
*/
|
|
||||||
static double Standard_DRT2LPS [9] = {
|
|
||||||
1,0,0,
|
|
||||||
0,0,-1,
|
|
||||||
0,1,0 };
|
|
||||||
|
|
||||||
static double PAElementsIEC[9] = {
|
|
||||||
1, 0, 0,
|
|
||||||
0, -1, 0,
|
|
||||||
0, 0, -1 };
|
|
||||||
|
|
||||||
static double LATElementsIEC[9] = {
|
|
||||||
0, 0, -1,
|
|
||||||
0, -1, 0,
|
|
||||||
-1, 0, 0};
|
|
||||||
|
|
||||||
static double HFS2IEC[9] = {
|
|
||||||
1, 0, 0,
|
|
||||||
0, 0, 1,
|
|
||||||
0, -1, 0};
|
|
||||||
|
|
||||||
static double FFS2IEC[9] = {
|
|
||||||
-1, 0, 0,
|
|
||||||
0, 0, -1,
|
|
||||||
0, -1, 0};
|
|
||||||
|
|
||||||
|
|
||||||
//FUNCTION DECLARATION NECESSARY FOR COPY/PASTE FROM vtkGDCMImageReader
|
//FUNCTION DECLARATION NECESSARY FOR COPY/PASTE FROM vtkGDCMImageReader
|
||||||
// const char *gGetStringValueFromTag(const gdcm::Tag& t, const gdcm::DataSet& ds);
|
// const char *gGetStringValueFromTag(const gdcm::Tag& t, const gdcm::DataSet& ds);
|
||||||
@ -97,6 +72,8 @@ itkImageProcessor::itkImageProcessor()
|
|||||||
// TZero[0]=TZero[1]=TZero[2]=0.;
|
// TZero[0]=TZero[1]=TZero[2]=0.;
|
||||||
// RZero[0]=RZero[1]=RZero[2]=0.;
|
// RZero[0]=RZero[1]=RZero[2]=0.;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
toVTK2D1 = ITKtoVTKFilterType::New();
|
toVTK2D1 = ITKtoVTKFilterType::New();
|
||||||
toVTK2D2 = ITKtoVTKFilterType::New();
|
toVTK2D2 = ITKtoVTKFilterType::New();
|
||||||
toVTKLocalizer1 = ITKtoVTKFilterType::New();
|
toVTKLocalizer1 = ITKtoVTKFilterType::New();
|
||||||
@ -217,7 +194,37 @@ itkImageProcessor::itkImageProcessor()
|
|||||||
|
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
// setup the Automatic Registration
|
||||||
|
metric = MetricType::New();
|
||||||
|
mimetric = MIMetricType::New();
|
||||||
|
optimizer = OptimizerType::New();
|
||||||
|
|
||||||
|
amoebaoptimizer = AmoebaOptimizerType::New();
|
||||||
|
|
||||||
|
optimizerObserver = CommandIterationUpdate::New();
|
||||||
|
|
||||||
|
exhaustiveOptimizer = ExhaustiveOptimizerType::New();
|
||||||
|
exhaustiveOptimizerObserver = ExhaustiveCommandIterationUpdate::New();
|
||||||
|
|
||||||
|
registration = RegistrationType::New();
|
||||||
|
|
||||||
|
if (m_UseMutualInformation) {
|
||||||
|
registration->SetMetric(mimetric);
|
||||||
|
} else {
|
||||||
|
registration->SetMetric(metric);
|
||||||
|
}
|
||||||
|
|
||||||
|
registration->SetOptimizer(optimizer);
|
||||||
|
registration->SetTransform1(transform1);
|
||||||
|
registration->SetTransform2(transform2);
|
||||||
|
registration->SetInterpolator1(interpolator1);
|
||||||
|
registration->SetInterpolator2(interpolator2);
|
||||||
|
|
||||||
|
m_UseExhaustiveOptmizer = false; //if the exhaustive optimizer shal be used, ovverrides ameoba
|
||||||
|
m_UseAmeobaOptimizer = false; //if the ameoba optimzer shall be used, otherwise Powell. Overriden by Exhaustive option.
|
||||||
|
m_UseFullROI = true; // if the full image ROI shall be used
|
||||||
|
m_UseMutualInformation = false; //oterwise NCC is used
|
||||||
|
m_UseDumptoFile = false; //If each (!) optimzer result shall be dumpped into a file.
|
||||||
}
|
}
|
||||||
|
|
||||||
itkImageProcessor::~itkImageProcessor()
|
itkImageProcessor::~itkImageProcessor()
|
||||||
@ -257,6 +264,17 @@ double itkImageProcessor::GetSCD2(){
|
|||||||
m_DRTImage1MetaInfo ->GetSCD();
|
m_DRTImage1MetaInfo ->GetSCD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void itkImageProcessor::SetDegreeOfFreedom(tDegreeOfFreedomEnum dof)
|
||||||
|
{
|
||||||
|
m_TransformMetaInfo->SetDegreeOfFreedom(dof);
|
||||||
|
}
|
||||||
|
|
||||||
|
tDegreeOfFreedomEnum
|
||||||
|
itkImageProcessor::GetDegreeOfFreedom()
|
||||||
|
{
|
||||||
|
return m_TransformMetaInfo->GetDegreeOfFreedom();
|
||||||
|
}
|
||||||
|
|
||||||
void itkImageProcessor::SetCustom_ImportTransform(double dTx,
|
void itkImageProcessor::SetCustom_ImportTransform(double dTx,
|
||||||
double dTy,
|
double dTy,
|
||||||
double dTz,
|
double dTz,
|
||||||
@ -384,8 +402,6 @@ void itkImageProcessor::SetCustom_2Dsize(int nX1, int nY1,int nX2,int nY2)
|
|||||||
|
|
||||||
void itkImageProcessor::SetCustom_UpdateMetaInfo(){
|
void itkImageProcessor::SetCustom_UpdateMetaInfo(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this->UpdateProjectionGeometryMeta();
|
this->UpdateProjectionGeometryMeta();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1254,6 +1270,35 @@ itkImageProcessor::MapTransformToNewOrigin(
|
|||||||
return m_OutputTransform;
|
return m_OutputTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This External User Transform thing need to be checked out
|
||||||
|
void itkImageProcessor::CalculateExternalUserTransform(TransformType::Pointer transform, DRTImageMetaInformation::Pointer imageMetaInfo)
|
||||||
|
{
|
||||||
|
//crude hack to get from internal transform in LPS to external transform in IEC.
|
||||||
|
//result is stored in m_TransformMetaInfo
|
||||||
|
|
||||||
|
//TODO: support for projectionTransformCenter and userTransformCenter which are not the same
|
||||||
|
//currentlz we support only pFakeIsoLPS situations.
|
||||||
|
|
||||||
|
InternalImageType::DirectionType LPStoIEC_Directions;
|
||||||
|
LPStoIEC_Directions = m_CTMetaInfo->GetLPS2IECDirections();
|
||||||
|
|
||||||
|
auto parameters = transform->GetParameters();
|
||||||
|
|
||||||
|
ImageType3D::PointType translationUser;
|
||||||
|
translationUser[0] = parameters[3];
|
||||||
|
translationUser[1] = parameters[4];
|
||||||
|
translationUser[2] = parameters[5];
|
||||||
|
ImageType3D::PointType rotationUser;
|
||||||
|
rotationUser[0] = parameters[0];
|
||||||
|
rotationUser[1] = parameters[1];
|
||||||
|
rotationUser[2] = parameters[2];
|
||||||
|
|
||||||
|
m_TransformMetaInfo->SetUserTranslations(LPStoIEC_Directions * translationUser);
|
||||||
|
m_TransformMetaInfo->SetUserRotations(LPStoIEC_Directions * rotationUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
itkImageProcessor::TransformType::Pointer
|
itkImageProcessor::TransformType::Pointer
|
||||||
itkImageProcessor::CalculateInternalTransform(
|
itkImageProcessor::CalculateInternalTransform(
|
||||||
ImageType3D::PointType m_TranslationOffset, //IEC
|
ImageType3D::PointType m_TranslationOffset, //IEC
|
||||||
@ -1323,6 +1368,362 @@ itkImageProcessor::CalculateInternalTransform(
|
|||||||
m_OutputTransform;
|
m_OutputTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void itkImageProcessor::InitializeRegistration(int maximumIteration, double stepLength, double maxTranslation, eDegreeOfFreedomType dof)
|
||||||
|
{
|
||||||
|
std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl;
|
||||||
|
|
||||||
|
if (!m_PASourceDupli) {
|
||||||
|
itkExceptionMacro(<< "PA topogram not present");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_LATSourceDupli) {
|
||||||
|
itkExceptionMacro(<< "LAT topogram not present");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_VolumeSourceDupli) {
|
||||||
|
itkExceptionMacro(<< "CT data not present");
|
||||||
|
}
|
||||||
|
|
||||||
|
metric->ComputeGradientOff();
|
||||||
|
metric->SetSubtractMean(true);
|
||||||
|
metric->SetMaxTranslation(maxTranslation);
|
||||||
|
|
||||||
|
m_TransformMetaInfo->SetDegreeOfFreedom(dof);
|
||||||
|
|
||||||
|
mimetric->ComputeGradientOff();
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
metric->DebugOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
registration->SetFixedImage1(m_PASourceDupli->GetOutput());
|
||||||
|
registration->SetFixedImage2(m_LATSourceDupli->GetOutput());
|
||||||
|
registration->SetMovingImage(m_VolumeSourceDupli->GetOutput());
|
||||||
|
|
||||||
|
//TODO: Here we could set the ROI for image registartion
|
||||||
|
|
||||||
|
auto region1 = m_PASourceDupli->GetOutput()->GetBufferedRegion();
|
||||||
|
auto region2 = m_LATSourceDupli->GetOutput()->GetBufferedRegion();
|
||||||
|
|
||||||
|
// bool setROI = false;
|
||||||
|
// if (setROI) {
|
||||||
|
// auto index1 = region1.GetIndex();
|
||||||
|
// auto size1 = region1.GetSize();
|
||||||
|
// auto point1 = m_PASourceDupli->GetOutput()->GetOrigin();
|
||||||
|
|
||||||
|
// index1[0] = size1[0] / 2 - 50;
|
||||||
|
// index1[1] = size1[1] / 2 - 50;
|
||||||
|
|
||||||
|
// size1[0] = 100;
|
||||||
|
// size1[1] = 100;
|
||||||
|
// size1[2] = 1;
|
||||||
|
|
||||||
|
// region1.SetIndex(index1);
|
||||||
|
// region1.SetSize(size1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
registration->SetFixedImageRegion1(region1);
|
||||||
|
registration->SetFixedImageRegion2(region2);
|
||||||
|
|
||||||
|
registration->SetTransformMetaInfo(m_TransformMetaInfo);
|
||||||
|
|
||||||
|
registration->SetFilter1(filter1);
|
||||||
|
registration->SetFilter2(filter2);
|
||||||
|
|
||||||
|
//CalculateInternalTransform(transform1, m_DRTImage1MetaInfo);
|
||||||
|
/********* BEGIN CALCULATION OF INTERNAL TRANSFORM FOR PROJ1 *********/
|
||||||
|
ImageType3D::PointType ZeroPoint;
|
||||||
|
ZeroPoint.Fill(0.);
|
||||||
|
InternalImageType::DirectionType IECtoLPS_Directions;
|
||||||
|
IECtoLPS_Directions =
|
||||||
|
m_CTMetaInfo->GetLPS2IECDirections().GetTranspose();
|
||||||
|
TransformType::Pointer CurrTransform;
|
||||||
|
if(m_RTMetaInfo == NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
//AAAAAA TODOOOOO CERCA
|
||||||
|
ImageType3D::PointType pFakeIsoLPS =
|
||||||
|
m_DRTImage1MetaInfo->GetProjectionOriginLPS();
|
||||||
|
//ImageType3D::PointType pFakeIsoLPS =
|
||||||
|
// m_CTMetaInfo->GetProjectionOriginLPS(
|
||||||
|
// m_DRTGeometryMetaInfo->GetProjectionCenter1());
|
||||||
|
CurrTransform =
|
||||||
|
CalculateInternalTransform(
|
||||||
|
ZeroPoint,
|
||||||
|
ZeroPoint,
|
||||||
|
m_TransformMetaInfo->GetTranslations(),
|
||||||
|
m_TransformMetaInfo->GetRotations(),
|
||||||
|
m_DRTImage1MetaInfo->GetProjectionOriginLPS(),
|
||||||
|
pFakeIsoLPS,
|
||||||
|
ZeroPoint,
|
||||||
|
IECtoLPS_Directions
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
CurrTransform =
|
||||||
|
CalculateInternalTransform(
|
||||||
|
ZeroPoint ,
|
||||||
|
m_DRTGeometryMetaInfo->GetIECS2IECScannerR(),
|
||||||
|
m_TransformMetaInfo->GetTranslations(),
|
||||||
|
m_TransformMetaInfo->GetRotations(),
|
||||||
|
m_DRTImage1MetaInfo->GetProjectionOriginLPS(),
|
||||||
|
m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(),
|
||||||
|
m_CTMetaInfo->GetImportOffset(),
|
||||||
|
IECtoLPS_Directions
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
transform1->SetComputeZYX(true);
|
||||||
|
transform1->SetIdentity();
|
||||||
|
transform1->SetTranslation(
|
||||||
|
CurrTransform->GetTranslation());
|
||||||
|
transform1->SetRotation(
|
||||||
|
CurrTransform->GetAngleX(),
|
||||||
|
CurrTransform->GetAngleY(),
|
||||||
|
CurrTransform->GetAngleZ()
|
||||||
|
);
|
||||||
|
transform1->SetCenter(
|
||||||
|
m_DRTImage1MetaInfo->GetProjectionOriginLPSZero() );
|
||||||
|
/********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/
|
||||||
|
|
||||||
|
|
||||||
|
//CalculateInternalTransform(transform2, m_DRTImage2MetaInfo);
|
||||||
|
/********* BEGIN CALCULATION OF INTERNAL TRANSFORM FOR PROJ2 *********/
|
||||||
|
if(m_RTMetaInfo == NULL)
|
||||||
|
{
|
||||||
|
ImageType3D::PointType pFakeIsoLPS =
|
||||||
|
m_DRTImage2MetaInfo->GetProjectionOriginLPS();
|
||||||
|
|
||||||
|
//ImageType3D::PointType pFakeIsoLPS =
|
||||||
|
// m_CTMetaInfo->GetProjectionOriginLPS(
|
||||||
|
// m_DRTGeometryMetaInfo->GetProjectionCenter2());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CurrTransform =
|
||||||
|
CalculateInternalTransform(
|
||||||
|
ZeroPoint,
|
||||||
|
ZeroPoint,
|
||||||
|
m_TransformMetaInfo->GetTranslations(),
|
||||||
|
m_TransformMetaInfo->GetRotations(),
|
||||||
|
m_DRTImage2MetaInfo->GetProjectionOriginLPS(),
|
||||||
|
pFakeIsoLPS,
|
||||||
|
ZeroPoint,
|
||||||
|
IECtoLPS_Directions
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
CurrTransform =
|
||||||
|
CalculateInternalTransform(
|
||||||
|
ZeroPoint ,
|
||||||
|
m_DRTGeometryMetaInfo->GetIECS2IECScannerR(),
|
||||||
|
m_TransformMetaInfo->GetTranslations(),
|
||||||
|
m_TransformMetaInfo->GetRotations(),
|
||||||
|
m_DRTImage2MetaInfo->GetProjectionOriginLPS(),
|
||||||
|
m_RTMetaInfo->GetIsocenterLPS() - m_CTMetaInfo->GetImportOffset(),
|
||||||
|
m_CTMetaInfo->GetImportOffset(),
|
||||||
|
IECtoLPS_Directions
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
transform2->SetComputeZYX(true);
|
||||||
|
transform2->SetIdentity();
|
||||||
|
transform2->SetTranslation(
|
||||||
|
CurrTransform->GetTranslation());
|
||||||
|
transform2->SetRotation(
|
||||||
|
CurrTransform->GetAngleX(),
|
||||||
|
CurrTransform->GetAngleY(),
|
||||||
|
CurrTransform->GetAngleZ()
|
||||||
|
);
|
||||||
|
transform2->SetCenter(
|
||||||
|
m_DRTImage2MetaInfo->GetProjectionOriginLPSZero() );
|
||||||
|
/********* END OF CALCULATE INTERNAL TRANSFORM FOR PROJ1 *********/
|
||||||
|
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
registration->DebugOn();
|
||||||
|
registration->Print(std::cout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_UseExhaustiveOptmizer) {
|
||||||
|
if (!m_UseAmeobaOptimizer) {
|
||||||
|
|
||||||
|
// The metric will return 0 or a "large" negative number in case of high correspondence of the images
|
||||||
|
// Thus, we need to minimze
|
||||||
|
optimizer->SetMaximize(false); // for NCC and MI
|
||||||
|
optimizer->SetMaximumIteration(maximumIteration);
|
||||||
|
optimizer->SetMaximumLineIteration(4); // for Powell's method
|
||||||
|
optimizer->SetStepLength(stepLength);
|
||||||
|
optimizer->SetStepTolerance(0.01);
|
||||||
|
optimizer->SetValueTolerance(0.000002);
|
||||||
|
if (verbose) {
|
||||||
|
optimizer->DebugOn();
|
||||||
|
optimizer->Print(std::cout);
|
||||||
|
}
|
||||||
|
|
||||||
|
optimizer->RemoveAllObservers();
|
||||||
|
optimizer->AddObserver(itk::IterationEvent(), optimizerObserver);
|
||||||
|
|
||||||
|
registration->SetOptimizer(optimizer);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
amoebaoptimizer->SetMinimize(true);
|
||||||
|
amoebaoptimizer->SetMaximumNumberOfIterations(100);
|
||||||
|
amoebaoptimizer->SetParametersConvergenceTolerance(0.1);
|
||||||
|
amoebaoptimizer->SetFunctionConvergenceTolerance(0.000002);
|
||||||
|
|
||||||
|
amoebaoptimizer->SetAutomaticInitialSimplex(false);
|
||||||
|
//Initial size of the simplex (otherwise it is a very small number and optimizer stops immeditaly)
|
||||||
|
// 2 mm / 2 degrees seems to be a good value which performs well.
|
||||||
|
OptimizerType::ParametersType simplexDelta(3);
|
||||||
|
int numberOfDOF = GetNumberOfDOF(dof);
|
||||||
|
if (numberOfDOF == 0) {
|
||||||
|
itkExceptionMacro(<< "Unkown or unsupported degree of freedom");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < numberOfDOF; i++) {
|
||||||
|
simplexDelta[i] = 2.0;
|
||||||
|
}
|
||||||
|
amoebaoptimizer->SetInitialSimplexDelta(simplexDelta);
|
||||||
|
|
||||||
|
amoebaoptimizer->RemoveAllObservers();
|
||||||
|
amoebaoptimizer->AddObserver(itk::IterationEvent(), optimizerObserver);
|
||||||
|
|
||||||
|
registration->SetOptimizer(amoebaoptimizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//only support for 3DOF
|
||||||
|
const int numberOfSteps = 25; //In each direction. Total number of steps is ((2*numberOfSteps+1))^3. For 25 -> 132651.
|
||||||
|
const double stepLength = 0.1;
|
||||||
|
|
||||||
|
auto parameters = transform1->GetParameters();
|
||||||
|
transform1->SetParameters(parameters);
|
||||||
|
|
||||||
|
ExhaustiveOptimizerType::StepsType steps(3);
|
||||||
|
steps[0] = numberOfSteps;
|
||||||
|
steps[1] = numberOfSteps;
|
||||||
|
steps[2] = numberOfSteps;
|
||||||
|
exhaustiveOptimizer->SetNumberOfSteps(steps);
|
||||||
|
exhaustiveOptimizer->SetStepLength(stepLength);
|
||||||
|
|
||||||
|
exhaustiveOptimizer->RemoveAllObservers();
|
||||||
|
exhaustiveOptimizer->AddObserver(itk::IterationEvent(), exhaustiveOptimizerObserver);
|
||||||
|
|
||||||
|
exhaustiveOptimizer->SetStepLength(stepLength);
|
||||||
|
registration->SetOptimizer(exhaustiveOptimizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "#" << __COMPACT_PRETTY_FUNCTION__ << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int itkImageProcessor::StartRegistration(std::string extraInfo)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl;
|
||||||
|
// TODO: Check if the registartion pipeline has been initialized
|
||||||
|
using ParametersType = RegistrationType::ParametersType;
|
||||||
|
|
||||||
|
auto startParameters = transform1->GetParameters();
|
||||||
|
|
||||||
|
time_t t = time(0); // get time now
|
||||||
|
struct tm* now = localtime(&t);
|
||||||
|
|
||||||
|
bool useDumpToFile = false;
|
||||||
|
|
||||||
|
char buffer[255];
|
||||||
|
strftime(buffer, 255, "test-%F-%H%M%S.txt", now);
|
||||||
|
|
||||||
|
std::fstream fs;
|
||||||
|
|
||||||
|
if (useDumpToFile || m_UseExhaustiveOptmizer) {
|
||||||
|
fs.open(buffer, std::fstream::out);
|
||||||
|
fs << extraInfo;
|
||||||
|
fs << "Value\tX\tY\tZ " << std::endl;
|
||||||
|
|
||||||
|
if (m_UseExhaustiveOptmizer) {
|
||||||
|
exhaustiveOptimizerObserver->set_stream(fs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the registration
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Create a timer to record calculation time.
|
||||||
|
itk::TimeProbesCollectorBase timer;
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
std::cout << "Starting the registration now..." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
timer.Start("Registration");
|
||||||
|
// Start the registration.
|
||||||
|
registration->StartRegistration();
|
||||||
|
timer.Stop("Registration");
|
||||||
|
} catch (itk::ExceptionObject& err) {
|
||||||
|
std::cout << "ExceptionObject caught !" << std::endl;
|
||||||
|
std::cout << err << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto oldprecision = fs.precision();
|
||||||
|
|
||||||
|
if (m_UseExhaustiveOptmizer) {
|
||||||
|
fs.precision(std::numeric_limits<double>::digits10 + 2);
|
||||||
|
fs << " MinimumMetricValue: " << exhaustiveOptimizer->GetMinimumMetricValue() << std::endl;
|
||||||
|
fs << " MaximumMetricValue: " << exhaustiveOptimizer->GetMaximumMetricValue() << std::endl;
|
||||||
|
fs.precision(oldprecision);
|
||||||
|
fs << " MinimumMetricValuePosition: " << exhaustiveOptimizer->GetMinimumMetricValuePosition() << std::endl;
|
||||||
|
fs << " MaximumMetricValuePosition: " << exhaustiveOptimizer->GetMaximumMetricValuePosition() << std::endl;
|
||||||
|
fs << " StopConditionDescription: " << exhaustiveOptimizer->GetStopConditionDescription() << std::endl;
|
||||||
|
fs << " MaximumMetricValuePosition: " << exhaustiveOptimizer->GetMaximumMetricValuePosition() << std::endl;
|
||||||
|
} else if (useDumpToFile) {
|
||||||
|
fs.precision(std::numeric_limits<double>::digits10 + 2);
|
||||||
|
fs << " FinalMetricValue: " << optimizer->GetValue() << std::endl; //same as GetCurrentCost
|
||||||
|
fs.precision(oldprecision);
|
||||||
|
fs << " FinalPosition: " << optimizer->GetCurrentPosition() << std::endl;
|
||||||
|
fs << " Iterations: " << optimizer->GetCurrentIteration() << std::endl;
|
||||||
|
fs << " StopConditionDescription: " << optimizer->GetStopConditionDescription() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.close();
|
||||||
|
|
||||||
|
m_OptmizerValue = optimizer->GetValue();
|
||||||
|
|
||||||
|
auto finalParameters = transform1->GetParameters();
|
||||||
|
optimizer->GetCurrentPosition();
|
||||||
|
finalParameters = finalParameters - startParameters;
|
||||||
|
|
||||||
|
TransformType::Pointer offsetTransform = TransformType::New();
|
||||||
|
offsetTransform->SetParameters(finalParameters);
|
||||||
|
|
||||||
|
CalculateExternalUserTransform(offsetTransform, m_DRTImage1MetaInfo);
|
||||||
|
|
||||||
|
const double translationAlongX = finalParameters[3];
|
||||||
|
const double translationAlongY = finalParameters[4];
|
||||||
|
const double translationAlongZ = finalParameters[5];
|
||||||
|
const double rotationAlongX = finalParameters[0];
|
||||||
|
const double rotationAlongY = finalParameters[1];
|
||||||
|
const double rotationAlongZ = finalParameters[2];
|
||||||
|
|
||||||
|
const int numberOfIterations = optimizer->GetCurrentIteration();
|
||||||
|
|
||||||
|
std::cout << "Result = " << std::endl;
|
||||||
|
std::cout << " Rotation Along X = " << rotationAlongX / dtr << " deg" << std::endl;
|
||||||
|
std::cout << " Rotation Along Y = " << rotationAlongY / dtr << " deg" << std::endl;
|
||||||
|
std::cout << " Rotation Along Z = " << rotationAlongZ / dtr << " deg" << std::endl;
|
||||||
|
std::cout << " Translation X = " << translationAlongX << " mm" << std::endl;
|
||||||
|
std::cout << " Translation Y = " << translationAlongY << " mm" << std::endl;
|
||||||
|
std::cout << " Translation Z = " << translationAlongZ << " mm" << std::endl;
|
||||||
|
std::cout << " Number Of Iterations = " << numberOfIterations << std::endl;
|
||||||
|
std::cout << " Metric value = " << m_OptmizerValue << std::endl;
|
||||||
|
|
||||||
|
std::cout << "#" << __COMPACT_PRETTY_FUNCTION__ << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void itkImageProcessor::InitializeProjector()
|
void itkImageProcessor::InitializeProjector()
|
||||||
{
|
{
|
||||||
@ -2643,6 +3044,85 @@ double* itkImageProcessor::GetTransformParameters(){
|
|||||||
return dTransfParam;
|
return dTransfParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Doubts about this user thing
|
||||||
|
void itkImageProcessor::GetFinalTranslations(double& dX, double& dY, double& dZ)
|
||||||
|
{
|
||||||
|
ImageType3D::PointType translations = m_TransformMetaInfo->GetTranslations();
|
||||||
|
ImageType3D::PointType userTranslations = m_TransformMetaInfo->GetUserTranslations();
|
||||||
|
|
||||||
|
dX = translations[0] + userTranslations[0];
|
||||||
|
dY = translations[1] + userTranslations[1];
|
||||||
|
dZ = translations[2] + userTranslations[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void itkImageProcessor::GetFinalRotations(double& dRX, double& dRY, double& dRZ)
|
||||||
|
{
|
||||||
|
ImageType3D::PointType rotations = m_TransformMetaInfo->GetRotations();
|
||||||
|
ImageType3D::PointType userRotations = m_TransformMetaInfo->GetUserRotations();
|
||||||
|
|
||||||
|
dRX = rotations[0] + userRotations[0];
|
||||||
|
dRY = rotations[1] + userRotations[1];
|
||||||
|
dRZ = rotations[2] + userRotations[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double itkImageProcessor::GetOptimizerValue()
|
||||||
|
{
|
||||||
|
return m_OptmizerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double itkImageProcessor::GetCurrentMetricValue()
|
||||||
|
{
|
||||||
|
//Note: this fails if the metric has not been propperly initilzed.
|
||||||
|
|
||||||
|
if (!m_UseMutualInformation) {
|
||||||
|
if (metric == NULL) {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
return metric->GetValue();
|
||||||
|
} else {
|
||||||
|
if (mimetric == NULL) {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
return mimetric->GetValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void itkImageProcessor::SetROI(double, double, double, double)
|
||||||
|
{
|
||||||
|
//TODO: Not implemanted yet. ROI are hard coded and can be enabled using SetFullROI.
|
||||||
|
}
|
||||||
|
|
||||||
|
void itkImageProcessor::SetOptimizer(std::string optimizer)
|
||||||
|
{
|
||||||
|
if (optimizer.compare("Powell") == 0) {
|
||||||
|
m_UseAmeobaOptimizer = false;
|
||||||
|
m_UseExhaustiveOptmizer = false;
|
||||||
|
} else if (optimizer.compare("Amoeba") == 0) {
|
||||||
|
m_UseExhaustiveOptmizer = false;
|
||||||
|
m_UseAmeobaOptimizer = true;
|
||||||
|
} else if (optimizer.compare("Exhaustive") == 0) {
|
||||||
|
m_UseExhaustiveOptmizer = true;
|
||||||
|
m_UseAmeobaOptimizer = false;
|
||||||
|
} else {
|
||||||
|
itkExceptionMacro(<< "Unkown optimzer string : " << optimizer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void itkImageProcessor::SetMetric(std::string metric)
|
||||||
|
{
|
||||||
|
if (metric.compare("NCC") == 0) {
|
||||||
|
m_UseMutualInformation = false;
|
||||||
|
} else if (metric.compare("MI") == 0) {
|
||||||
|
m_UseMutualInformation = true;
|
||||||
|
} else {
|
||||||
|
itkExceptionMacro(<< "Unkown metric string : " << optimizer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void itkImageProcessor::SetFullROI(bool fullROI)
|
||||||
|
{
|
||||||
|
m_UseFullROI = fullROI;
|
||||||
|
// TODO: Remove this function when ROI functinalitz has been implemented.
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace itk
|
} // end namespace itk
|
||||||
|
|
||||||
|
@ -30,6 +30,13 @@ gfattori 08.11.2021
|
|||||||
#include "itkObjectFactory.h"
|
#include "itkObjectFactory.h"
|
||||||
#include "itkSmartPointer.h"
|
#include "itkSmartPointer.h"
|
||||||
|
|
||||||
|
#include "itkExhaustiveOptimizer.h"
|
||||||
|
#include "itkMutualInformationTwoImageToOneImageMetric.h"
|
||||||
|
#include "itkNormalizedCorrelationTwoImageToOneImageMetric.h"
|
||||||
|
#include "itkPowellOptimizer.h"
|
||||||
|
#include "itkTwoProjectionImageRegistrationMethod.h"
|
||||||
|
#include "itkAmoebaOptimizer.h"
|
||||||
|
|
||||||
#include "itkImageToVTKImageFilter.h"
|
#include "itkImageToVTKImageFilter.h"
|
||||||
|
|
||||||
#include "itkImageFileReader.h"
|
#include "itkImageFileReader.h"
|
||||||
@ -46,13 +53,104 @@ gfattori 08.11.2021
|
|||||||
|
|
||||||
namespace itk
|
namespace itk
|
||||||
{
|
{
|
||||||
/* reference string required for comparison with tag values */
|
|
||||||
static const char *ImageOrientationStrings[] = {
|
class CommandIterationUpdate : public itk::Command {
|
||||||
"NotDefined",
|
// TODO: Move to own files.
|
||||||
"HFS",
|
|
||||||
"FFS"
|
public:
|
||||||
|
using Self = CommandIterationUpdate;
|
||||||
|
using Superclass = itk::Command;
|
||||||
|
using Pointer = itk::SmartPointer<Self>;
|
||||||
|
itkNewMacro(Self);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CommandIterationUpdate() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using OptimizerType = itk::PowellOptimizer;
|
||||||
|
using OptimizerPointer = const OptimizerType*;
|
||||||
|
|
||||||
|
using AmoebaOptimizerType = itk::AmoebaOptimizer;
|
||||||
|
;
|
||||||
|
using AmoebaOptimizerPointer = const OptimizerType*;
|
||||||
|
|
||||||
|
void
|
||||||
|
Execute(itk::Object* caller, const itk::EventObject& event) override
|
||||||
|
{
|
||||||
|
Execute((const itk::Object*)caller, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Execute(const itk::Object* object, const itk::EventObject& event) override
|
||||||
|
{
|
||||||
|
auto optimizer = dynamic_cast<OptimizerPointer>(object);
|
||||||
|
if (typeid(event) == typeid(itk::IterationEvent)) {
|
||||||
|
|
||||||
|
//Feedback from the optimizer executed at the end of every itteration
|
||||||
|
// currently just print the result into the cout. We might add
|
||||||
|
// functionality to register and emit signals to update the UI.
|
||||||
|
|
||||||
|
std::cout << "Iteration: " << optimizer->GetCurrentIteration() << std::endl;
|
||||||
|
auto oldprecision = std::cout.precision();
|
||||||
|
std::cout.precision(std::numeric_limits<double>::digits10 + 2);
|
||||||
|
std::cout << "Similarity: " << optimizer->GetValue() << std::endl;
|
||||||
|
std::cout.precision(oldprecision);
|
||||||
|
std::cout << "Position: " << optimizer->GetCurrentPosition() << std::endl;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ExhaustiveCommandIterationUpdate : public itk::Command {
|
||||||
|
// TODO: Move to own files.
|
||||||
|
|
||||||
|
public:
|
||||||
|
using Self = ExhaustiveCommandIterationUpdate;
|
||||||
|
using Superclass = itk::Command;
|
||||||
|
using Pointer = itk::SmartPointer<Self>;
|
||||||
|
itkNewMacro(Self);
|
||||||
|
|
||||||
|
std::ostream* os;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ExhaustiveCommandIterationUpdate() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using OptimizerType = itk::ExhaustiveOptimizer;
|
||||||
|
;
|
||||||
|
using OptimizerPointer = const OptimizerType*;
|
||||||
|
|
||||||
|
void set_stream(std::ostream& stream)
|
||||||
|
{
|
||||||
|
os = &stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Execute(itk::Object* caller, const itk::EventObject& event) override
|
||||||
|
{
|
||||||
|
Execute((const itk::Object*)caller, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Execute(const itk::Object* object, const itk::EventObject& event) override
|
||||||
|
{
|
||||||
|
auto optimizer = dynamic_cast<OptimizerPointer>(object);
|
||||||
|
if (typeid(event) == typeid(itk::IterationEvent)) {
|
||||||
|
|
||||||
|
//crude LPS to IEC transform for HFS.
|
||||||
|
auto position = optimizer->GetCurrentPosition();
|
||||||
|
|
||||||
|
auto oldprecision = os->precision();
|
||||||
|
os->precision(std::numeric_limits<double>::digits10 + 2);
|
||||||
|
*os << optimizer->GetCurrentValue();
|
||||||
|
os->precision(oldprecision);
|
||||||
|
*os << "\t" << position[0] << "\t" << position[2] << "\t" << -position[1] << std::endl;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class ITK_EXPORT itkImageProcessor : public itk::Object
|
class ITK_EXPORT itkImageProcessor : public itk::Object
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -97,6 +195,10 @@ public:
|
|||||||
double GetSCD1();
|
double GetSCD1();
|
||||||
double GetSCD2();
|
double GetSCD2();
|
||||||
|
|
||||||
|
/** Sets the degree of freedom for omptimzation*/
|
||||||
|
void SetDegreeOfFreedom(tDegreeOfFreedomEnum);
|
||||||
|
tDegreeOfFreedomEnum GetDegreeOfFreedom();
|
||||||
|
|
||||||
void SetCustom_ProjectionCenterOffsetFixedAxes_IEC(double,double,double,double,double,double);
|
void SetCustom_ProjectionCenterOffsetFixedAxes_IEC(double,double,double,double,double,double);
|
||||||
|
|
||||||
void SetCustom_ProjectionCenterFixedAxes_IEC(double,double,double);
|
void SetCustom_ProjectionCenterFixedAxes_IEC(double,double,double);
|
||||||
@ -117,6 +219,19 @@ public:
|
|||||||
void SetInitialTranslations(double, double, double);
|
void SetInitialTranslations(double, double, double);
|
||||||
void SetInitialRotations(double, double, double);
|
void SetInitialRotations(double, double, double);
|
||||||
|
|
||||||
|
/** Get transform parameters for 3D Volume */
|
||||||
|
void GetFinalTranslations(double&, double&, double&);
|
||||||
|
void GetFinalRotations(double&, double&, double&);
|
||||||
|
|
||||||
|
/** Set user transform parameters for 3D Volume in LPS*/
|
||||||
|
void SetUserTranslationsLPS(double, double, double);
|
||||||
|
void SetUserRotationsLPS(double, double, double);
|
||||||
|
|
||||||
|
/** Initialize the registration pipeline*/
|
||||||
|
void InitializeRegistration(int, double, double, eDegreeOfFreedomType);
|
||||||
|
/** Start the registration process*/
|
||||||
|
int StartRegistration(std::string extraInfo);
|
||||||
|
|
||||||
/** Get transform parameters for 3D Volume */
|
/** Get transform parameters for 3D Volume */
|
||||||
double* GetTransformParameters();
|
double* GetTransformParameters();
|
||||||
|
|
||||||
@ -129,8 +244,6 @@ public:
|
|||||||
/** Get Projection origin in LPS coordinates*/
|
/** Get Projection origin in LPS coordinates*/
|
||||||
const std::vector <double> GetRTImportOffset();
|
const std::vector <double> GetRTImportOffset();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Get the Localizer intensity window and
|
/** Get the Localizer intensity window and
|
||||||
* center for rendering */
|
* center for rendering */
|
||||||
double GetLocalizerDisplayWindowLevel(int );
|
double GetLocalizerDisplayWindowLevel(int );
|
||||||
@ -153,6 +266,17 @@ public:
|
|||||||
void WriteProjectionImages();
|
void WriteProjectionImages();
|
||||||
void Write2DImages();
|
void Write2DImages();
|
||||||
|
|
||||||
|
/** Get the current cost function value from the optimizer*/
|
||||||
|
double GetOptimizerValue();
|
||||||
|
|
||||||
|
/** Get the cost function value for the current transform*/
|
||||||
|
double GetCurrentMetricValue();
|
||||||
|
|
||||||
|
void SetROI(double, double, double, double);
|
||||||
|
|
||||||
|
void SetOptimizer(std::string);
|
||||||
|
void SetMetric(std::string);
|
||||||
|
void SetFullROI(bool);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -189,6 +313,16 @@ private:
|
|||||||
using InterpolatorType = itk::gSiddonJacobsRayCastInterpolateImageFunction<InternalImageType, double>;
|
using InterpolatorType = itk::gSiddonJacobsRayCastInterpolateImageFunction<InternalImageType, double>;
|
||||||
using ResampleFilterType = itk::ResampleImageFilter<InternalImageType, InternalImageType>;
|
using ResampleFilterType = itk::ResampleImageFilter<InternalImageType, InternalImageType>;
|
||||||
|
|
||||||
|
/** Optimizer which tries to find the minimn (Powell Optimizer)*/
|
||||||
|
using OptimizerType = itk::PowellOptimizer;
|
||||||
|
using AmoebaOptimizerType = itk::AmoebaOptimizer;
|
||||||
|
/** Optimizer which samples the whol space */
|
||||||
|
using ExhaustiveOptimizerType = itk::ExhaustiveOptimizer;
|
||||||
|
/** Metric to calculate similarites between images*/
|
||||||
|
using MetricType = itk::NormalizedCorrelationTwoImageToOneImageMetric<InternalImageType, InternalImageType>;
|
||||||
|
using MIMetricType = itk::MutualInformationTwoImageToOneImageMetric<InternalImageType, InternalImageType>;
|
||||||
|
/** The thing which actuall does the image registration*/
|
||||||
|
using RegistrationType = itk::TwoProjectionImageRegistrationMethod<InternalImageType, InternalImageType>;
|
||||||
|
|
||||||
/** Image reader types */
|
/** Image reader types */
|
||||||
using ImageReaderType2D = itk::ImageFileReader<ImageType2D>;
|
using ImageReaderType2D = itk::ImageFileReader<ImageType2D>;
|
||||||
@ -206,6 +340,8 @@ private:
|
|||||||
/** ITK to VTK filter */
|
/** ITK to VTK filter */
|
||||||
using ITKtoVTKFilterType = itk::ImageToVTKImageFilter<OutputImageType>;
|
using ITKtoVTKFilterType = itk::ImageToVTKImageFilter<OutputImageType>;
|
||||||
|
|
||||||
|
void
|
||||||
|
CalculateExternalUserTransform(TransformType::Pointer transform, DRTImageMetaInformation::Pointer imageMetaInfo);
|
||||||
|
|
||||||
TransformType::Pointer
|
TransformType::Pointer
|
||||||
CalculateInternalTransform(
|
CalculateInternalTransform(
|
||||||
@ -239,6 +375,23 @@ private:
|
|||||||
imageDRT1In,
|
imageDRT1In,
|
||||||
imageDRT2In;
|
imageDRT2In;
|
||||||
|
|
||||||
|
RegistrationType::Pointer
|
||||||
|
registration;
|
||||||
|
MetricType::Pointer
|
||||||
|
metric;
|
||||||
|
MIMetricType::Pointer
|
||||||
|
mimetric;
|
||||||
|
OptimizerType::Pointer
|
||||||
|
optimizer;
|
||||||
|
AmoebaOptimizerType::Pointer
|
||||||
|
amoebaoptimizer;
|
||||||
|
CommandIterationUpdate::Pointer
|
||||||
|
optimizerObserver;
|
||||||
|
ExhaustiveOptimizerType::Pointer
|
||||||
|
exhaustiveOptimizer;
|
||||||
|
ExhaustiveCommandIterationUpdate::Pointer
|
||||||
|
exhaustiveOptimizerObserver;
|
||||||
|
|
||||||
DuplicatorType::Pointer
|
DuplicatorType::Pointer
|
||||||
m_LATSourceDupli,
|
m_LATSourceDupli,
|
||||||
m_PASourceDupli,
|
m_PASourceDupli,
|
||||||
@ -335,6 +488,15 @@ private:
|
|||||||
TransformMetaInformation::Pointer
|
TransformMetaInformation::Pointer
|
||||||
m_TransformMetaInfo;
|
m_TransformMetaInfo;
|
||||||
|
|
||||||
|
|
||||||
|
double m_OptmizerValue;
|
||||||
|
|
||||||
|
bool m_UseExhaustiveOptmizer;
|
||||||
|
bool m_UseAmeobaOptimizer;
|
||||||
|
bool m_UseFullROI;
|
||||||
|
bool m_UseMutualInformation;
|
||||||
|
bool m_UseDumptoFile;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user