Merge branch 'ScoutRTUIDevelOptim' into 'ScoutRTUIDevel'
First integration of Automatic Registration is running (on Approve button).... See merge request cpt_bioeng/drt!20
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