Added dialogs for approval and Automatic Registration. Added abort of auto registration

This commit is contained in:
Proton local user
2023-02-22 15:09:26 +01:00
parent d82bd12ef9
commit 085f8e0900
10 changed files with 308 additions and 139 deletions

View File

@ -23,6 +23,7 @@ SET(SRCS
SET(HDR SET(HDR
itkImageProcessor.h itkImageProcessor.h
itkQtIterationUpdate.h
itkgSiddonJacobsRayCastInterpolateImageFunction.h itkgSiddonJacobsRayCastInterpolateImageFunction.h
itkgSiddonJacobsRayCastInterpolateImageFunction.hxx itkgSiddonJacobsRayCastInterpolateImageFunction.hxx
vtkContourTopogramProjectionFilter.h vtkContourTopogramProjectionFilter.h

View File

@ -35,7 +35,7 @@ static const char* ImageOrientationStrings[] = {
// constant for converting degrees into radians // constant for converting degrees into radians
const float dtr = itk::Math::pi_over_180; const float dtr = itk::Math::pi_over_180;
static const bool verbose = true; static const bool verbose = false;
/* this is in the end a IEC to HFS... /* this is in the end a IEC to HFS...
* but we keep this for ourselves... * but we keep this for ourselves...

View File

@ -25,6 +25,8 @@
#include "itkNormalizeImageFilter.h" #include "itkNormalizeImageFilter.h"
#include "itkTranslationTransform.h" #include "itkTranslationTransform.h"
#include "itkProgressReporter.h"
#include <limits> #include <limits>
namespace itk { namespace itk {

View File

@ -211,11 +211,11 @@ NormalizedCorrelationTwoImageToOneImageMetric<TFixedImage, TMovingImage>::Calcul
} else { } else {
measure = NumericTraits<MeasureType>::Zero; measure = NumericTraits<MeasureType>::Zero;
} }
std::cout << "movingValueMin: " << movingValueMin << " movingValueMax: " << movingValueMax << std::endl;
std::cout << "fixedValueMin: " << fixedValueMin << " fixedValueMax: " << fixedValueMax << std::endl;
std::cout << "max coordinates: " << maxX << " " << maxX << " " << maxZ << std::endl; // std::cout << "movingValueMin: " << movingValueMin << " movingValueMax: " << movingValueMax << std::endl;
std::cout << "min coordinates: " << minX << " " << minY << " " << minZ << std::endl; // std::cout << "fixedValueMin: " << fixedValueMin << " fixedValueMax: " << fixedValueMax << std::endl;
// std::cout << "max coordinates: " << maxX << " " << maxX << " " << maxZ << std::endl;
// std::cout << "min coordinates: " << minX << " " << minY << " " << minZ << std::endl;
return measure; return measure;
} }
@ -275,18 +275,19 @@ NormalizedCorrelationTwoImageToOneImageMetric<TFixedImage, TMovingImage>::GetVal
auto oldprecision = std::cout.precision(); auto oldprecision = std::cout.precision();
MeasureType measure1 = CalculateMeasure(1); MeasureType measure1 = CalculateMeasure(1);
std::cout.precision(std::numeric_limits<double>::digits10 + 2); // std::cout.precision(std::numeric_limits<double>::digits10 + 2);
std::cout << "Measure1: " << measure1 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; // std::cout << "Measure1: " << measure1 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl;
std::cout.precision(oldprecision); // std::cout.precision(oldprecision);
MeasureType measure2 = CalculateMeasure(2); MeasureType measure2 = CalculateMeasure(2);
std::cout.precision(std::numeric_limits<double>::digits10 + 2); // std::cout.precision(std::numeric_limits<double>::digits10 + 2);
std::cout << "Measure2: " << measure2 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl; // std::cout << "Measure2: " << measure2 << " Counts: " << this->m_NumberOfPixelsCounted << std::endl;
auto measure = (measure1 + measure2) / 2.0; auto measure = (measure1 + measure2) / 2.0;
std::cout << "Measure: " << measure << std::endl;
std::cout << "=======================================================" << std::endl; // std::cout << "Measure: " << measure << std::endl;
std::cout.precision(oldprecision); // std::cout << "=======================================================" << std::endl;
// std::cout.precision(oldprecision);
return measure; return measure;
} }

View File

@ -25,6 +25,10 @@
#include "itkProcessObject.h" #include "itkProcessObject.h"
#include "itkSingleValuedNonLinearOptimizer.h" #include "itkSingleValuedNonLinearOptimizer.h"
#include "itkgTwoImageToOneImageMetric.h" #include "itkgTwoImageToOneImageMetric.h"
#include "itkObject.h"
#include "itkEventObject.h"
#include <iostream> #include <iostream>
namespace itk { namespace itk {
@ -231,6 +235,11 @@ protected:
/** Provides derived classes with the ability to set this private var */ /** Provides derived classes with the ability to set this private var */
itkSetMacro(LastOptimizerParameters, ParametersType); itkSetMacro(LastOptimizerParameters, ParametersType);
/** Entry-point for internal ITK filter observer. **/
void OnInternalFilterProgressReceptor(itk::Object *caller,
const itk::EventObject &event);
private: private:
MetricPointer m_Metric; MetricPointer m_Metric;
OptimizerType::Pointer m_Optimizer; OptimizerType::Pointer m_Optimizer;

View File

@ -18,6 +18,8 @@
#ifndef itkTwoProjectionImageRegistrationMethod_hxx #ifndef itkTwoProjectionImageRegistrationMethod_hxx
#define itkTwoProjectionImageRegistrationMethod_hxx #define itkTwoProjectionImageRegistrationMethod_hxx
#include "itkCommand.h"
#include "itkTwoProjectionImageRegistrationMethod.h" #include "itkTwoProjectionImageRegistrationMethod.h"
namespace itk { namespace itk {
@ -175,6 +177,32 @@ void TwoProjectionImageRegistrationMethod<TFixedImage, TMovingImage>::Initialize
m_Optimizer->SetInitialPosition(m_InitialOptimizerParameters); m_Optimizer->SetInitialPosition(m_InitialOptimizerParameters);
} }
template <typename TFixedImage, typename TMovingImage>
void TwoProjectionImageRegistrationMethod<TFixedImage, TMovingImage>::OnInternalFilterProgressReceptor(
itk::Object *caller, const itk::EventObject &event)
{
itk::ProcessObject *filter = dynamic_cast<itk::ProcessObject *>(caller);
if(!itk::ProgressEvent().CheckEvent(&event) || !filter)
return;
if (filter)
{
// double p = m_CurrentProgressStart;
// // filter->GetProgress() in [0;1]
// p += m_CurrentProgressSpan * filter->GetProgress();
// // NOTE: filter is buggy - not in [0;1] if multi-threading is activated!
// if (p > (m_CurrentProgressStart + m_CurrentProgressSpan))
// p = m_CurrentProgressStart + m_CurrentProgressSpan;
// TaskProgressInfo(m_CurrentProgressDirection, p);
// if (m_CancelRequest)
// filter->SetAbortGenerateData(true); // may be handled by filter
std::cout << "Porca Madonna " << std::endl;
}
}
/* /*
* Starts the Registration Process * Starts the Registration Process
*/ */
@ -182,6 +210,22 @@ template <typename TFixedImage, typename TMovingImage>
void TwoProjectionImageRegistrationMethod<TFixedImage, TMovingImage>::StartRegistration() void TwoProjectionImageRegistrationMethod<TFixedImage, TMovingImage>::StartRegistration()
{ {
// typedef itk::MemberCommand<TwoProjectionImageRegistrationMethod> ITKCommandType;
// typedef ITKCommandType::Pointer MemberPointer ;
// ITKCommandType::Pointer cmd = ITKCommandType::New();
// itk::Command cmd= itk::Command::Pointer(this);
// cmd->SetCallbackFunction(this,
// (ITKCommandType::Pointer)&TwoProjectionImageRegistrationMethod::OnInternalFilterProgressReceptor);
itk::ProgressReporter progress(
this,
1, 1000,100);
// this->SetAbortGenerateData(true);
ParametersType empty(1); ParametersType empty(1);
empty.Fill(0.0); empty.Fill(0.0);
try { try {
@ -253,6 +297,7 @@ void TwoProjectionImageRegistrationMethod<TFixedImage, TMovingImage>::PrintSelf(
template <typename TFixedImage, typename TMovingImage> template <typename TFixedImage, typename TMovingImage>
void TwoProjectionImageRegistrationMethod<TFixedImage, TMovingImage>::GenerateData() void TwoProjectionImageRegistrationMethod<TFixedImage, TMovingImage>::GenerateData()
{ {
this->StartRegistration(); this->StartRegistration();
} }

View File

@ -97,14 +97,14 @@ bool gTwoImageToOneImageMetric<TFixedImage, TMovingImage>::SetTransformParameter
break; break;
} }
std::cout << "New Transform Parameters = " << std::endl; // std::cout << "New Transform Parameters = " << std::endl;
std::cout << " Translation X = " << TranslationAlongX << " mm" << std::endl; // std::cout << " Translation X = " << TranslationAlongX << " mm" << std::endl;
std::cout << " Translation Y = " << TranslationAlongY << " mm" << std::endl; // std::cout << " Translation Y = " << TranslationAlongY << " mm" << std::endl;
std::cout << " Translation Z = " << TranslationAlongZ << " mm" << std::endl; // std::cout << " Translation Z = " << TranslationAlongZ << " mm" << std::endl;
std::cout << " Rotation Along X = " << RotationAlongX / dtr << " deg" << 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 Y = " << RotationAlongY / dtr << " deg" << std::endl;
std::cout << " Rotation Along Z = " << RotationAlongZ / dtr << " deg" << std::endl; // std::cout << " Rotation Along Z = " << RotationAlongZ / dtr << " deg" << std::endl;
std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; // std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
transformParameters[0] = RotationAlongX; transformParameters[0] = RotationAlongX;
transformParameters[1] = RotationAlongY; transformParameters[1] = RotationAlongY;

View File

@ -1,4 +1,4 @@

/* /*
@ -25,6 +25,8 @@ gfattori 08.11.2021
#include "itkOrientImageFilter.h" #include "itkOrientImageFilter.h"
#include <gdcmIPPSorter.h> #include <gdcmIPPSorter.h>
#include "itkCommand.h"
#include "itkTimeProbesCollectorBase.h" #include "itkTimeProbesCollectorBase.h"
#include <string> #include <string>
@ -200,13 +202,14 @@ itkImageProcessor::itkImageProcessor()
optimizer = OptimizerType::New(); optimizer = OptimizerType::New();
amoebaoptimizer = AmoebaOptimizerType::New(); amoebaoptimizer = AmoebaOptimizerType::New();
optimizerObserver = CommandIterationUpdate::New(); optimizerObserver = CommandIterationUpdate::New();
exhaustiveOptimizer = ExhaustiveOptimizerType::New(); exhaustiveOptimizer = ExhaustiveOptimizerType::New();
exhaustiveOptimizerObserver = ExhaustiveCommandIterationUpdate::New(); exhaustiveOptimizerObserver = ExhaustiveCommandIterationUpdate::New();
registration = RegistrationType::New(); registration = RegistrationType::New();
optimizerObserver->SetProcess(registration);
if (m_UseMutualInformation) { if (m_UseMutualInformation) {
registration->SetMetric(mimetric); registration->SetMetric(mimetric);
@ -1368,7 +1371,7 @@ itkImageProcessor::CalculateInternalTransform(
m_OutputTransform; m_OutputTransform;
} }
void itkImageProcessor::InitializeRegistration(int maximumIteration, double stepLength, double maxTranslation, eDegreeOfFreedomType dof) void itkImageProcessor::InitializeRegistration(double stepLength, double maxTranslation, eDegreeOfFreedomType dof)
{ {
std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl; std::cout << "*" << __COMPACT_PRETTY_FUNCTION__ << std::endl;
@ -1396,6 +1399,7 @@ void itkImageProcessor::InitializeRegistration(int maximumIteration, double step
metric->DebugOn(); metric->DebugOn();
} }
registration->SetFixedImage1(m_PASourceDupli->GetOutput()); registration->SetFixedImage1(m_PASourceDupli->GetOutput());
registration->SetFixedImage2(m_LATSourceDupli->GetOutput()); registration->SetFixedImage2(m_LATSourceDupli->GetOutput());
registration->SetMovingImage(m_VolumeSourceDupli->GetOutput()); registration->SetMovingImage(m_VolumeSourceDupli->GetOutput());
@ -1553,7 +1557,7 @@ void itkImageProcessor::InitializeRegistration(int maximumIteration, double step
// The metric will return 0 or a "large" negative number in case of high correspondence of the images // The metric will return 0 or a "large" negative number in case of high correspondence of the images
// Thus, we need to minimze // Thus, we need to minimze
optimizer->SetMaximize(false); // for NCC and MI optimizer->SetMaximize(false); // for NCC and MI
optimizer->SetMaximumIteration(maximumIteration); optimizer->SetMaximumIteration(m_MaxNumberOfIterations);
optimizer->SetMaximumLineIteration(4); // for Powell's method optimizer->SetMaximumLineIteration(4); // for Powell's method
optimizer->SetStepLength(stepLength); optimizer->SetStepLength(stepLength);
optimizer->SetStepTolerance(0.01); optimizer->SetStepTolerance(0.01);
@ -1563,10 +1567,13 @@ void itkImageProcessor::InitializeRegistration(int maximumIteration, double step
optimizer->Print(std::cout); optimizer->Print(std::cout);
} }
optimizer->RemoveAllObservers(); optimizer->RemoveAllObservers();
optimizer->AddObserver(itk::IterationEvent(), optimizerObserver); optimizer->AddObserver(itk::AnyEvent(), optimizerObserver);
registration->SetOptimizer(optimizer); registration->SetOptimizer(optimizer);
registration->RemoveAllObservers();
} else { } else {
amoebaoptimizer->SetMinimize(true); amoebaoptimizer->SetMinimize(true);
@ -1658,11 +1665,13 @@ int itkImageProcessor::StartRegistration(std::string extraInfo)
} }
try { try {
timer.Start("Registration"); // timer.Start("Registration");
// Start the registration. // Start the registration.
registration->StartRegistration(); registration->StartRegistration();
timer.Stop("Registration"); // timer.Stop("Registration");
} catch (itk::ExceptionObject& err) { } catch (itk::ExceptionObject& err) {
registration->ResetPipeline();
std::cout << "ExceptionObject caught !" << std::endl; std::cout << "ExceptionObject caught !" << std::endl;
std::cout << err << std::endl; std::cout << err << std::endl;
return -1; return -1;
@ -1728,7 +1737,8 @@ int itkImageProcessor::StartRegistration(std::string extraInfo)
void itkImageProcessor::InitializeProjector() void itkImageProcessor::InitializeProjector()
{ {
// std::cout<< "itkImageProcessor::InitializeProjector()" <<std::endl;
if(m_DRTImage1MetaInfo == NULL || if(m_DRTImage1MetaInfo == NULL ||
m_DRTImage2MetaInfo == NULL || m_DRTImage2MetaInfo == NULL ||
m_DRTGeometryMetaInfo == NULL || m_DRTGeometryMetaInfo == NULL ||
@ -3124,5 +3134,11 @@ void itkImageProcessor::SetFullROI(bool fullROI)
// TODO: Remove this function when ROI functinalitz has been implemented. // TODO: Remove this function when ROI functinalitz has been implemented.
} }
void itkImageProcessor::SetMaxNumberOfIterations(int iNum)
{
m_MaxNumberOfIterations = iNum;
// TODO: Remove this function when ROI functinalitz has been implemented.
}
} // end namespace itk } // end namespace itk

View File

@ -45,112 +45,15 @@ gfattori 08.11.2021
#include "gdcmGlobal.h" #include "gdcmGlobal.h"
#include "vtkImageData.h" #include "vtkImageData.h"
#include "vtkTransform.h" #include "vtkTransform.h"
#include "vtkSmartPointer.h" #include "vtkSmartPointer.h"
#include "itkQtIterationUpdate.h"
namespace itk namespace itk
{ {
class CommandIterationUpdate : public itk::Command {
// TODO: Move to own files.
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
{ {
@ -169,6 +72,11 @@ public:
/** Run-time type information (and related methods). */ /** Run-time type information (and related methods). */
itkTypeMacro(itkImageProcessor, Object); itkTypeMacro(itkImageProcessor, Object);
CommandIterationUpdate::Pointer
optimizerObserver;
/** Input data load methods*/ /** Input data load methods*/
int load3DSerieFromFolder(const char* ); int load3DSerieFromFolder(const char* );
int load3DSerieFromFiles( std::vector<std::string> ); int load3DSerieFromFiles( std::vector<std::string> );
@ -228,7 +136,7 @@ public:
void SetUserRotationsLPS(double, double, double); void SetUserRotationsLPS(double, double, double);
/** Initialize the registration pipeline*/ /** Initialize the registration pipeline*/
void InitializeRegistration(int, double, double, eDegreeOfFreedomType); void InitializeRegistration(double, double, eDegreeOfFreedomType);
/** Start the registration process*/ /** Start the registration process*/
int StartRegistration(std::string extraInfo); int StartRegistration(std::string extraInfo);
@ -277,7 +185,10 @@ public:
void SetOptimizer(std::string); void SetOptimizer(std::string);
void SetMetric(std::string); void SetMetric(std::string);
void SetFullROI(bool); void SetFullROI(bool);
void SetMaxNumberOfIterations(int);
/** Optimizer which tries to find the minimn (Powell Optimizer)*/
using OptimizerType = itk::PowellOptimizer;
protected: protected:
/** Various pixel types */ /** Various pixel types */
@ -299,7 +210,7 @@ private:
/** Fill Meta after 3D volume load */ /** Fill Meta after 3D volume load */
int fill3DVolumeMeta(InternalImageType::Pointer, int fill3DVolumeMeta(InternalImageType::Pointer,
tPatOrientation); tPatOrientation);
/** Image types */ /** Image types */
using ImageType2D = itk::Image<PixelType3D, Dimension>; using ImageType2D = itk::Image<PixelType3D, Dimension>;
@ -314,7 +225,7 @@ private:
using ResampleFilterType = itk::ResampleImageFilter<InternalImageType, InternalImageType>; using ResampleFilterType = itk::ResampleImageFilter<InternalImageType, InternalImageType>;
/** Optimizer which tries to find the minimn (Powell Optimizer)*/ /** Optimizer which tries to find the minimn (Powell Optimizer)*/
using OptimizerType = itk::PowellOptimizer; // using OptimizerType = itk::PowellOptimizer;
using AmoebaOptimizerType = itk::AmoebaOptimizer; using AmoebaOptimizerType = itk::AmoebaOptimizer;
/** Optimizer which samples the whol space */ /** Optimizer which samples the whol space */
using ExhaustiveOptimizerType = itk::ExhaustiveOptimizer; using ExhaustiveOptimizerType = itk::ExhaustiveOptimizer;
@ -376,21 +287,19 @@ private:
imageDRT2In; imageDRT2In;
RegistrationType::Pointer RegistrationType::Pointer
registration; registration;
MetricType::Pointer MetricType::Pointer
metric; metric;
MIMetricType::Pointer MIMetricType::Pointer
mimetric; mimetric;
OptimizerType::Pointer OptimizerType::Pointer
optimizer; optimizer;
AmoebaOptimizerType::Pointer AmoebaOptimizerType::Pointer
amoebaoptimizer; amoebaoptimizer;
CommandIterationUpdate::Pointer
optimizerObserver;
ExhaustiveOptimizerType::Pointer ExhaustiveOptimizerType::Pointer
exhaustiveOptimizer; exhaustiveOptimizer;
ExhaustiveCommandIterationUpdate::Pointer ExhaustiveCommandIterationUpdate::Pointer
exhaustiveOptimizerObserver; exhaustiveOptimizerObserver;
DuplicatorType::Pointer DuplicatorType::Pointer
m_LATSourceDupli, m_LATSourceDupli,
@ -490,6 +399,7 @@ private:
double m_OptmizerValue; double m_OptmizerValue;
int m_MaxNumberOfIterations;
bool m_UseExhaustiveOptmizer; bool m_UseExhaustiveOptmizer;
bool m_UseAmeobaOptimizer; bool m_UseAmeobaOptimizer;

View File

@ -0,0 +1,185 @@
#ifndef ITKQTITERATIONUPDATE_H
#define ITKQTITERATIONUPDATE_H
#include "itkCommand.h"
#include <QObject>
#include "itkPowellOptimizer.h"
#include "itkAmoebaOptimizer.h"
#include "itkExhaustiveOptimizer.h"
#include "itkTwoProjectionImageRegistrationMethod.h"
class QObjectIterationUpdate : public QObject{
Q_OBJECT
public:
QObjectIterationUpdate(){
bAbortProcessCommand = false;
};
bool getAbortFlag(){
return bAbortProcessCommand;
};
void setAbortFlag(bool bVal){
bAbortProcessCommand = bVal;
};
public slots:
void onAbortProcessCommand(){
std::cout << " Abort STOCAZZO " << std::endl;
bAbortProcessCommand = true;
};
void onIteration(double dI,double dX,double dY,double dZ){
emit
sendRegistrationProgress(dI,dX,dY,dZ);
}
private:
bool
bAbortProcessCommand;
signals:
void sendRegistrationProgress(double,double,double,double);
};
namespace itk
{
class CommandIterationUpdate : public itk::Command {
// TODO: Move to own files.
constexpr static unsigned int Dimension = 3;
public:
QObjectIterationUpdate *objIterUpdate;
using Self = CommandIterationUpdate;
using Superclass = itk::Command;
using Pointer = itk::SmartPointer<Self>;
itkNewMacro(CommandIterationUpdate);
using InternalPixelType = float;
using InternalImageType = itk::Image<InternalPixelType, Dimension>;
using ProcesssType = typename itk::TwoProjectionImageRegistrationMethod<InternalImageType, InternalImageType>;
using ProcesssPointer = typename ProcesssType::Pointer;
/** Set/Get the Process. */
itkSetObjectMacro(Process, ProcesssType);
itkGetConstObjectMacro(Process, ProcesssType);
private:
protected:
CommandIterationUpdate() {
objIterUpdate = new QObjectIterationUpdate;
}
ProcesssPointer m_Process;
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
{
if(objIterUpdate->getAbortFlag()){
std::cout << "Abortisci per piacere" << std::endl;
objIterUpdate->setAbortFlag(false);
throw itk::ProcessAborted();
}
// std::cout << "Progress: " << this->m_Process->GetAbortGenerateData() << std::endl;
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;
objIterUpdate->onIteration(
optimizer->GetCurrentIteration()+1,
optimizer->GetCurrentPosition()[0],
optimizer->GetCurrentPosition()[2],
-optimizer->GetCurrentPosition()[1]
);
}
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;
}
};
}
#endif