CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxElastixExecuter.h
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 
13 #ifndef CXELASTIXEXECUTER_H_
14 #define CXELASTIXEXECUTER_H_
15 
16 #include <QString>
17 #include "cxForwardDeclarations.h"
18 #include "cxTransform3D.h"
19 #include <QObject>
20 #include <QProcess>
21 #include <QFile>
22 #include "cxTimedAlgorithm.h"
23 #include "cxLogger.h"
24 #include "cxRegServices.h"
25 #include "org_custusx_registration_method_commandline_Export.h"
26 
27 namespace cx
28 {
49 class org_custusx_registration_method_commandline_EXPORT ElastixExecuter : public TimedBaseAlgorithm
50 {
51  Q_OBJECT
52 public:
53  ElastixExecuter(RegServicesPtr services, QObject* parent=NULL);
54  virtual ~ElastixExecuter();
55 
56  void setDisplayProcessMessages(bool on);
57 
58  bool setInput(QString application,
59  DataPtr fixed,
60  DataPtr moving,
61  QString outdir,
62  QStringList parameterfiles);
63  virtual void execute();
64  virtual bool isFinished() const;
65  virtual bool isRunning() const;
66 
72  Transform3D getAffineResult_mMf(bool* ok = 0) ;
73  QString getNonlinearResultVolume(bool* ok = 0);
74 
75 private slots:
76  void processStateChanged(QProcess::ProcessState newState);
77  void processError(QProcess::ProcessError error);
78  void processFinished(int, QProcess::ExitStatus);
79  void processReadyRead();
80 
81 private:
85  QString writeInitTransformToElastixfile(DataPtr fixed, DataPtr moving, QString outdir);
89  QString writeInitTransformToCalfile(DataPtr fixed, DataPtr moving, QString outdir);
94  QString findMostRecentTransformOutputFile() const;
113  Transform3D getAffineResult_mmMff(bool* ok = 0) ;
120  Transform3D getFileTransform_ddMd(DataPtr volume);
121 
122  QString mLastOutdir;
123  QProcess* mProcess;
124  DataPtr mFixed;
125  DataPtr mMoving;
126  RegServicesPtr mServices;
127 };
128 
133 {
134 public:
135  ElastixParameterFile(QString filename);
136 
137  bool isValid() const;
138  QString readParameterString(QString key) ;
139  bool readParameterBool(QString key) ;
140  int readParameterInt(QString key) ;
141  std::vector<double> readParameterDoubleVector(QString key) ;
142 // void writeParameter(QString key, QStringList value);
143  Transform3D readEulerTransform() ;
144  Transform3D readAffineTransform();
145 
146 private:
147  QString readParameterRawValue(QString key);
148  QFile mFile;
149  QString mText;
150 };
151 
157 {
158 public:
162 
163  static ElastixEulerTransform create(Vector3D angles_xyz, Vector3D translation, Vector3D centerOfRotation)
164  {
165  ElastixEulerTransform retval;
166  retval.mAngles_xyz = angles_xyz;
167  retval.mTranslation = translation;
168  retval.mCenterOfRotation = centerOfRotation;
169  return retval;
170  }
171  static ElastixEulerTransform create(Transform3D M, Vector3D centerOfRotation)
172  {
173  ElastixEulerTransform retval;
174  retval.mAngles_xyz = M.matrix().block<3, 3> (0, 0).eulerAngles(0, 1, 2);
175  retval.mCenterOfRotation = centerOfRotation;
176 
177  Transform3D R = retval.getRotationMatrix();
179  // solve M = T*Tc*R*Tc.inv() with respect to T:
180  Transform3D T = M*C*R.inv()*C.inv();
181 
182  retval.mTranslation = T.matrix().block<3, 1> (0, 3);
183 // retval.mCenterOfRotation = Vector3D(0,0,0);
184  return retval;
185  }
187  {
188  Transform3D T = createTransformTranslate(mTranslation);
189  Transform3D C = createTransformTranslate(mCenterOfRotation);
190  Transform3D R = this->getRotationMatrix();
191  Transform3D Q = T*C*R*C.inv();
192  return Q;
193  }
194  static void test()
195  {
196  std::cout << "==========TEST==============" << std::endl;
198 
199  ElastixEulerTransform E = create(M, Vector3D(30,40,50));
200  Transform3D Q = E.toMatrix();
201 
202  std::cout << "M\n" << M << std::endl;
203  std::cout << "Q\n" << Q << std::endl;
204  Transform3D diff = Q*M.inv();
205  std::cout << "Q*M.inv\n" << diff << std::endl;
206  if (!similar(Transform3D::Identity(), diff))
207  reportError("assertion failure in ElastixEulerTransform");
208  }
209 private:
211 
212  Transform3D getRotationMatrix() const
213  {
214  Eigen::Matrix3d m;
215  m = Eigen::AngleAxisd(mAngles_xyz[0], Eigen::Vector3d::UnitX())
216  * Eigen::AngleAxisd(mAngles_xyz[1], Eigen::Vector3d::UnitY())
217  * Eigen::AngleAxisd(mAngles_xyz[2], Eigen::Vector3d::UnitZ());
218 
219  Transform3D R = Transform3D::Identity();
220  R.matrix().block<3, 3> (0, 0) = m;
221  return R;
222  }
223 };
224 
225 
229 } /* namespace cx */
230 #endif /* CXELASTIXEXECUTER_H_ */
Transform3D createTransformRotateY(const double angle)
void reportError(QString msg)
Definition: cxLogger.cpp:71
Base class for algorithms that wants to time their execution.
static ElastixEulerTransform create(Vector3D angles_xyz, Vector3D translation, Vector3D centerOfRotation)
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
Transform3D toMatrix() const
static ElastixEulerTransform create(Transform3D M, Vector3D centerOfRotation)
boost::shared_ptr< class Data > DataPtr
ElastiX command-line wrapper.
boost::shared_ptr< class RegServices > RegServicesPtr
Definition: cxRegServices.h:20
Transform3D createTransformTranslate(const Vector3D &translation)
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
Transform3D createTransformRotateX(const double angle)
#define M_PI
Namespace for all CustusX production code.