219 lines
5.5 KiB
C++
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
|
|
|