35 #include <ctkPluginContext.h>
36 #include <ctkServiceTracker.h>
37 #include <vtkPoints.h>
38 #include <vtkLandmarkTransform.h>
39 #include <vtkMatrix4x4.h>
58 mLastRegistrationTime(QDateTime::currentDateTime()),
78 void RegistrationImplService::duringSavePatientSlot(QDomElement& node)
81 QDomElement managerNode = root.descend(
"managers").node().toElement();
82 this->addXml(managerNode);
87 void RegistrationImplService::duringLoadPatientSlot(QDomElement& node)
89 XMLNodeParser root(node);
90 QDomElement registrationManager = root.descend(
"managers/registrationManager").node().toElement();
91 if (!registrationManager.isNull())
92 this->parseXml(registrationManager);
98 void RegistrationImplService::addXml(QDomNode& parentNode)
100 QDomDocument doc = parentNode.ownerDocument();
101 QDomElement base = doc.createElement(
"registrationManager");
102 parentNode.appendChild(base);
104 QDomElement fixedDataNode = doc.createElement(
"fixedDataUid");
108 fixedDataNode.appendChild(doc.createTextNode(fixedData->getUid()));
110 base.appendChild(fixedDataNode);
112 QDomElement movingDataNode = doc.createElement(
"movingDataUid");
116 movingDataNode.appendChild(doc.createTextNode(movingData->getUid()));
118 base.appendChild(movingDataNode);
121 void RegistrationImplService::parseXml(QDomNode& dataNode)
123 QString fixedData = dataNode.namedItem(
"fixedDataUid").toElement().text();
124 this->
setFixedData(mPatientModelService->getData(fixedData));
126 QString movingData = dataNode.namedItem(
"movingDataUid").toElement().text();
127 this->
setMovingData(mPatientModelService->getData(movingData));
130 void RegistrationImplService::clearSlot()
140 mMovingData = movingData;
146 if(mFixedData == fixedData)
149 mFixedData = fixedData;
151 report(
"Registration fixed data set to "+mFixedData->getUid());
167 return mLastRegistrationTime;
173 mLastRegistrationTime = time;
182 reportError(
"The fixed data is not set, cannot do patient registration!");
185 LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
186 LandmarkMap toolLandmarks = mPatientModelService->getPatientLandmarks()->getLandmarks();
188 this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
189 this->writePreLandmarkRegistration(
"physical", toolLandmarks);
191 std::vector<QString> landmarks = this->getUsableLandmarks(fixedLandmarks, toolLandmarks);
193 vtkPointsPtr p_ref = this->convertTovtkPoints(landmarks, fixedLandmarks, fixedImage->get_rMd());
194 vtkPointsPtr p_pr = this->convertTovtkPoints(landmarks, toolLandmarks, Transform3D::Identity());
197 if (p_ref->GetNumberOfPoints() < 3)
201 Transform3D rMpr = this->performLandmarkRegistration(p_pr, p_ref, &ok);
204 reportError(
"P-I Landmark registration: Failed to register: [" +
qstring_cast(p_pr->GetNumberOfPoints()) +
"p]");
216 reportError(
"The fixed data is not set, cannot do image registration!");
220 LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
221 LandmarkMap toolLandmarks = mPatientModelService->getPatientLandmarks()->getLandmarks();
223 this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
224 this->writePreLandmarkRegistration(
"physical", toolLandmarks);
226 std::vector<QString> landmarks = this->getUsableLandmarks(fixedLandmarks, toolLandmarks);
229 Transform3D rMpr_old = mPatientModelService->get_rMpr();
230 std::vector<Vector3D> p_pr_old = this->convertAndTransformToPoints(landmarks, fixedLandmarks, rMpr_old.inv()*rMd);
231 std::vector<Vector3D> p_pr_new = this->convertAndTransformToPoints(landmarks, toolLandmarks, Transform3D::Identity());
234 if (p_pr_old.size() < 1)
242 reportError(
"Fast translation registration: Failed to register: [" +
qstring_cast(p_pr_old.size()) +
"points]");
271 std::vector<Vector3D> RegistrationImplService::convertAndTransformToPoints(
const std::vector<QString>& uids,
const LandmarkMap& data,
Transform3D M)
273 std::vector<Vector3D> retval;
275 for (
unsigned i=0; i<uids.size(); ++i)
277 QString uid = uids[i];
278 Vector3D p = M.coord(data.find(uid)->second.getCoord());
288 std::vector<QString> RegistrationImplService::getUsableLandmarks(
const LandmarkMap& data_a,
const LandmarkMap& data_b)
290 std::vector<QString> retval;
291 std::map<QString, LandmarkProperty> props = mPatientModelService->getLandmarkProperties();
292 std::map<QString, LandmarkProperty>::iterator iter;
294 for (iter=props.begin(); iter!=props.end(); ++iter)
296 QString uid = iter->first;
297 if (data_a.count(uid) && data_b.count(uid) && iter->second.getActive())
298 retval.push_back(uid);
309 reportError(
"The fixed data is not set, cannot do landmark image registration!");
317 reportError(
"The moving data is not set, cannot do landmark image registration!");
322 if(movingImage==fixedImage)
324 reportError(
"The moving and fixed are equal, ignoring landmark image registration!");
328 LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
329 LandmarkMap imageLandmarks = movingImage->getLandmarks()->getLandmarks();
331 this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
332 this->writePreLandmarkRegistration(movingImage->getName(), movingImage->getLandmarks()->getLandmarks());
334 std::vector<QString> landmarks = getUsableLandmarks(fixedLandmarks, imageLandmarks);
335 vtkPointsPtr p_fixed_r = convertTovtkPoints(landmarks, fixedLandmarks, fixedImage->get_rMd());
336 vtkPointsPtr p_moving_r = convertTovtkPoints(landmarks, imageLandmarks, movingImage->get_rMd());
338 int minNumberOfPoints = 3;
340 minNumberOfPoints = 1;
343 if (p_fixed_r->GetNumberOfPoints() < minNumberOfPoints)
346 QString(
"Found %1 corresponding landmarks, need %2, cannot do landmark image registration!")
347 .arg(p_fixed_r->GetNumberOfPoints())
348 .arg(minNumberOfPoints)
360 delta = landmarkTransReg.
registerPoints(convertVtkPointsToPoints(p_fixed_r), convertVtkPointsToPoints(p_moving_r), &ok);
361 idString = QString(
"Image to Image Landmark Translation");
366 delta = this->performLandmarkRegistration(p_moving_r, p_fixed_r, &ok);
367 idString = QString(
"Image to Image Landmark");
372 reportError(
"I-I Landmark registration: Failed to register: [" +
qstring_cast(p_moving_r->GetNumberOfPoints()) +
"p], "+ movingImage->getName());
379 std::vector<Vector3D> RegistrationImplService::convertVtkPointsToPoints(
vtkPointsPtr base)
381 std::vector<Vector3D> retval;
383 for (
int i=0; i<base->GetNumberOfPoints(); ++i)
399 if (source->GetNumberOfPoints() < 3)
401 return Transform3D::Identity();
405 landmarktransform->SetSourceLandmarks(source);
406 landmarktransform->SetTargetLandmarks(target);
407 landmarktransform->SetModeToRigidBody();
410 landmarktransform->Update();
412 Transform3D tar_M_src(landmarktransform->GetMatrix());
414 if (QString::number(tar_M_src(0,0))==
"nan")
416 return Transform3D::Identity();
426 regTrans.
mFixed = mFixedData ? mFixedData->getUid() :
"";
427 regTrans.
mMoving = mMovingData ? mMovingData->getUid() :
"";
429 this->updateRegistration(mLastRegistrationTime, regTrans, mMovingData);
432 reportSuccess(QString(
"Image registration [%1] has been performed on %2").arg(description).arg(regTrans.
mMoving) );
448 regTrans.
mFixed = mFixedData ? mFixedData->getUid() :
"";
450 mPatientModelService->updateRegistration_rMpr(mLastRegistrationTime, regTrans);
453 reportSuccess(QString(
"Patient registration [%1] has been performed.").arg(description));
465 mPatientModelService->autoSave();
477 Transform3D rMpr = mPatientModelService->get_rMpr();
490 QString description(
"Patient Orientation");
503 std::map<QString,DataPtr> data = mPatientModelService->getData();
505 for (std::map<QString,DataPtr>::iterator iter = data.begin(); iter!=data.end(); ++iter)
507 DataPtr current = iter->second;
509 newTransform.
mValue = regTrans.
mValue * current->get_rMd();
510 current->get_rMd_History()->updateRegistration(oldTime, newTransform);
512 report(
"Updated registration of data " + current->getName());
513 std::cout <<
"rMd_new\n" << newTransform.
mValue << std::endl;
521 void RegistrationImplService::writePreLandmarkRegistration(QString name,
LandmarkMap landmarks)
524 for (LandmarkMap::iterator iter=landmarks.begin(); iter!=landmarks.end(); ++iter)
526 lm << mPatientModelService->getLandmarkProperties()[iter->second.getUid()].getName();
529 QString msg = QString(
"Preparing to register [%1] containing the landmarks: [%2]").arg(name).arg(lm.join(
","));
543 for (
unsigned i=0; i<uids.size(); ++i)
545 QString uid = uids[i];
546 Vector3D p = M.coord(data.find(uid)->second.getCoord());
547 retval->InsertNextPoint(p.begin());
QString qstring_cast(const T &val)
void reportError(QString msg)
void isLoading(QDomElement &root)
emitted while loading a session. Xml storage is available, getRootFolder() is set to loaded value...
RegistrationImplService(ctkPluginContext *context)
virtual void doFastRegistration_Orientation(const Transform3D &tMtm, const Transform3D &prMt)
vtkSmartPointer< class vtkLandmarkTransform > vtkLandmarkTransformPtr
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
QString getFixedDataUid()
virtual QDateTime getLastRegistrationTime()
virtual void doImageRegistration(bool translationOnly)
virtual ~RegistrationImplService()
virtual void setFixedData(DataPtr data)
virtual void doFastRegistration_Translation()
use the landmarks in master image and patient to perform a translation-only landmark registration ...
void fixedDataChanged(QString uid)
virtual DataPtr getFixedData()
virtual DataPtr getMovingData()
boost::shared_ptr< class Data > DataPtr
Transform3D registerPoints(std::vector< Vector3D > ref, std::vector< Vector3D > target, bool *ok)
QString getMovingDataUid()
virtual void updateRegistration(QDateTime oldTime, RegistrationTransform deltaTransform, DataPtr data)
virtual void setMovingData(DataPtr data)
virtual void doPatientRegistration()
registrates the fixed image to the patient
void reportSuccess(QString msg)
void cleared()
emitted when session is cleared, before isLoading is called
virtual void setLastRegistrationTime(QDateTime time)
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
void movingDataChanged(QString uid)
virtual void applyPatientOrientation(const Transform3D &tMtm, const Transform3D &prMt)
Identical to doFastRegistration_Orientation(), except data does not move.
std::map< QString, class Landmark > LandmarkMap
Always provides a PatientModelService.
virtual void applyPatientRegistration(Transform3D rMpr_new, QString description)
virtual void applyImage2ImageRegistration(Transform3D delta_pre_rMd, QString description)
void isSaving(QDomElement &root)
xml storage is available
vtkSmartPointer< class vtkPoints > vtkPointsPtr