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

219 lines
5.5 KiB
C++

#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(){
bAbortProcessCommand = true;
};
void onIteration(itk::tOptimizerTypeEnum eType,double dI,double dX,double dY,double dZ){
switch (eType) {
case itk::eOptimizerType::POWELL:
emit
sendRegistrationProgress(0,dI,dX,dY,dZ);
break;
case itk::eOptimizerType::AMOEBA:
emit
sendRegistrationProgress(1,dI,dX,dY,dZ);
break;
default:
break;
}
}
private:
bool
bAbortProcessCommand;
signals:
void sendRegistrationProgress(int,double,double,double,double);
};
namespace itk
{
class CommandIterationUpdate : public itk::Command {
constexpr static unsigned int Dimension = 3;
public:
QObjectIterationUpdate *objIterUpdate;
tOptimizerTypeEnum
eOptimType;
int
iAmoebaIterations;
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 AmoebaOptimizerType*;
void setOptimizerTypeOfIterationUpdate(tOptimizerTypeEnum eOptType){
eOptimType = eOptType;
iAmoebaIterations = 0;
}
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 << "AbortRequest" << std::endl;
objIterUpdate->setAbortFlag(false);
throw itk::ProcessAborted();
}
OptimizerPointer optPow;
AmoebaOptimizerPointer optAm;
switch (eOptimType) {
case eOptimizerType::POWELL:
optPow = dynamic_cast<OptimizerPointer>(object);
if (typeid(event) == typeid(itk::IterationEvent)) {
objIterUpdate->onIteration(
eOptimType,
optPow->GetCurrentIteration()+1,
optPow->GetCurrentPosition()[0],
optPow->GetCurrentPosition()[1],
optPow->GetCurrentPosition()[2]
);
}
break;
case eOptimizerType::AMOEBA:
optAm = dynamic_cast<AmoebaOptimizerPointer>(object);
iAmoebaIterations ++;
objIterUpdate->onIteration(
eOptimType,
iAmoebaIterations, //optAm->GetCachedValue(),
optAm->GetCachedCurrentPosition()[0],
optAm->GetCachedCurrentPosition()[1],
optAm->GetCachedCurrentPosition()[2]
);
break;
default:
break;
}
return;
}
};
class ExhaustiveCommandIterationUpdate : public itk::Command {
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;
*os << "\t" << position[0] << "\t" << position[1] << "\t" << position[2] << std::endl;
}
return;
}
};
}
#endif