35 #include <ctkPluginContext.h>
36 #include <ctkServiceTracker.h>
37 #include <vtkPoints.h>
38 #include <vtkLandmarkTransform.h>
39 #include <vtkMatrix4x4.h>
58 mLastRegistrationTime(QDateTime::currentDateTime()),
72 void RegistrationImplService::duringSavePatientSlot(QDomElement& node)
75 QDomElement managerNode = root.descend(
"managers").node().toElement();
76 this->addXml(managerNode);
79 void RegistrationImplService::duringLoadPatientSlot(QDomElement& node)
81 XMLNodeParser root(node);
82 QDomElement registrationManager = root.descend(
"managers/registrationManager").node().toElement();
83 if (!registrationManager.isNull())
84 this->parseXml(registrationManager);
87 void RegistrationImplService::addXml(QDomNode& parentNode)
89 QDomDocument doc = parentNode.ownerDocument();
90 QDomElement base = doc.createElement(
"registrationManager");
91 parentNode.appendChild(base);
93 QDomElement fixedDataNode = doc.createElement(
"fixedDataUid");
97 fixedDataNode.appendChild(doc.createTextNode(fixedData->getUid()));
99 base.appendChild(fixedDataNode);
101 QDomElement movingDataNode = doc.createElement(
"movingDataUid");
105 movingDataNode.appendChild(doc.createTextNode(movingData->getUid()));
107 base.appendChild(movingDataNode);
110 void RegistrationImplService::parseXml(QDomNode& dataNode)
112 QString fixedData = dataNode.namedItem(
"fixedDataUid").toElement().text();
115 QString movingData = dataNode.namedItem(
"movingDataUid").toElement().text();
119 void RegistrationImplService::clearSlot()
137 if (uid==mMovingData)
153 return mPatientModelService->getData(mMovingData);
158 return mPatientModelService->getData(mFixedData);
163 return mLastRegistrationTime;
168 mLastRegistrationTime = time;
177 reportError(
"The fixed data is not set, cannot do patient registration!");
180 LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
181 LandmarkMap toolLandmarks = mPatientModelService->getPatientLandmarks()->getLandmarks();
183 this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
184 this->writePreLandmarkRegistration(
"physical", toolLandmarks);
186 std::vector<QString> landmarks = this->getUsableLandmarks(fixedLandmarks, toolLandmarks);
188 vtkPointsPtr p_ref = this->convertTovtkPoints(landmarks, fixedLandmarks, fixedImage->get_rMd());
189 vtkPointsPtr p_pr = this->convertTovtkPoints(landmarks, toolLandmarks, Transform3D::Identity());
192 if (p_ref->GetNumberOfPoints() < 3)
196 Transform3D rMpr = this->performLandmarkRegistration(p_pr, p_ref, &ok);
199 reportError(
"P-I Landmark registration: Failed to register: [" +
qstring_cast(p_pr->GetNumberOfPoints()) +
"p]");
211 reportError(
"The fixed data is not set, cannot do image registration!");
215 LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
216 LandmarkMap toolLandmarks = mPatientModelService->getPatientLandmarks()->getLandmarks();
218 this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
219 this->writePreLandmarkRegistration(
"physical", toolLandmarks);
221 std::vector<QString> landmarks = this->getUsableLandmarks(fixedLandmarks, toolLandmarks);
224 Transform3D rMpr_old = mPatientModelService->get_rMpr();
225 std::vector<Vector3D> p_pr_old = this->convertAndTransformToPoints(landmarks, fixedLandmarks, rMpr_old.inv()*rMd);
226 std::vector<Vector3D> p_pr_new = this->convertAndTransformToPoints(landmarks, toolLandmarks, Transform3D::Identity());
229 if (p_pr_old.size() < 1)
237 reportError(
"Fast translation registration: Failed to register: [" +
qstring_cast(p_pr_old.size()) +
"points]");
266 std::vector<Vector3D> RegistrationImplService::convertAndTransformToPoints(
const std::vector<QString>& uids,
const LandmarkMap& data,
Transform3D M)
268 std::vector<Vector3D> retval;
270 for (
unsigned i=0; i<uids.size(); ++i)
272 QString uid = uids[i];
273 Vector3D p = M.coord(data.find(uid)->second.getCoord());
283 std::vector<QString> RegistrationImplService::getUsableLandmarks(
const LandmarkMap& data_a,
const LandmarkMap& data_b)
285 std::vector<QString> retval;
286 std::map<QString, LandmarkProperty> props = mPatientModelService->getLandmarkProperties();
287 std::map<QString, LandmarkProperty>::iterator iter;
289 for (iter=props.begin(); iter!=props.end(); ++iter)
291 QString uid = iter->first;
292 if (data_a.count(uid) && data_b.count(uid) && iter->second.getActive())
293 retval.push_back(uid);
304 reportError(
"The fixed data is not set, cannot do landmark image registration!");
312 reportError(
"The moving data is not set, cannot do landmark image registration!");
317 if(movingImage==fixedImage)
319 reportError(
"The moving and fixed are equal, ignoring landmark image registration!");
323 LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
324 LandmarkMap imageLandmarks = movingImage->getLandmarks()->getLandmarks();
326 this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
327 this->writePreLandmarkRegistration(movingImage->getName(), movingImage->getLandmarks()->getLandmarks());
329 std::vector<QString> landmarks = getUsableLandmarks(fixedLandmarks, imageLandmarks);
330 vtkPointsPtr p_fixed_r = convertTovtkPoints(landmarks, fixedLandmarks, fixedImage->get_rMd());
331 vtkPointsPtr p_moving_r = convertTovtkPoints(landmarks, imageLandmarks, movingImage->get_rMd());
333 int minNumberOfPoints = 3;
335 minNumberOfPoints = 1;
338 if (p_fixed_r->GetNumberOfPoints() < minNumberOfPoints)
341 QString(
"Found %1 corresponding landmarks, need %2, cannot do landmark image registration!")
342 .arg(p_fixed_r->GetNumberOfPoints())
343 .arg(minNumberOfPoints)
355 delta = landmarkTransReg.
registerPoints(convertVtkPointsToPoints(p_fixed_r), convertVtkPointsToPoints(p_moving_r), &ok);
356 idString = QString(
"Image to Image Landmark Translation");
361 delta = this->performLandmarkRegistration(p_moving_r, p_fixed_r, &ok);
362 idString = QString(
"Image to Image Landmark");
367 reportError(
"I-I Landmark registration: Failed to register: [" +
qstring_cast(p_moving_r->GetNumberOfPoints()) +
"p], "+ movingImage->getName());
374 std::vector<Vector3D> RegistrationImplService::convertVtkPointsToPoints(
vtkPointsPtr base)
376 std::vector<Vector3D> retval;
378 for (
int i=0; i<base->GetNumberOfPoints(); ++i)
394 if (source->GetNumberOfPoints() < 3)
396 return Transform3D::Identity();
400 landmarktransform->SetSourceLandmarks(source);
401 landmarktransform->SetTargetLandmarks(target);
402 landmarktransform->SetModeToRigidBody();
405 landmarktransform->Update();
407 Transform3D tar_M_src(landmarktransform->GetMatrix());
409 if (QString::number(tar_M_src(0,0))==
"nan")
411 return Transform3D::Identity();
420 this->performImage2ImageRegistration(delta_pre_rMd, description);
425 this->performImage2ImageRegistration(delta_pre_rMd, description,
true);
428 void RegistrationImplService::performImage2ImageRegistration(
Transform3D delta_pre_rMd, QString description,
bool continuous)
431 regTrans.mFixed = mFixedData;
432 regTrans.mMoving = mMovingData;
434 this->updateRegistration(mLastRegistrationTime, regTrans, this->
getMovingData(), continuous);
436 mLastRegistrationTime = regTrans.mTimestamp;
438 reportSuccess(QString(
"Image registration [%1] has been performed on %2").arg(description).arg(regTrans.mMoving) );
443 this->performPatientRegistration(rMpr_new, description);
448 this->performPatientRegistration(rMpr_new, description,
true);
451 void RegistrationImplService::performPatientRegistration(
Transform3D rMpr_new, QString description,
bool continuous)
454 regTrans.mFixed = mFixedData;
456 mPatientModelService->updateRegistration_rMpr(mLastRegistrationTime, regTrans, continuous);
458 mLastRegistrationTime = regTrans.mTimestamp;
460 reportSuccess(QString(
"Patient registration [%1] has been performed.").arg(description));
468 void RegistrationImplService::updateRegistration(QDateTime oldTime, RegistrationTransform deltaTransform,
DataPtr data,
bool continuous)
470 RegistrationApplicator applicator(mPatientModelService->getData());
471 applicator.updateRegistration(oldTime, deltaTransform, data, continuous);
473 mPatientModelService->autoSave();
485 Transform3D rMpr = mPatientModelService->get_rMpr();
498 QString description(
"Patient Orientation");
511 std::map<QString,DataPtr> data = mPatientModelService->getData();
513 for (std::map<QString,DataPtr>::iterator iter = data.begin(); iter!=data.end(); ++iter)
515 DataPtr current = iter->second;
517 newTransform.
mValue = regTrans.
mValue * current->get_rMd();
518 current->get_rMd_History()->updateRegistration(oldTime, newTransform);
520 report(
"Updated registration of data " + current->getName());
521 std::cout <<
"rMd_new\n" << newTransform.
mValue << std::endl;
529 void RegistrationImplService::writePreLandmarkRegistration(QString name,
LandmarkMap landmarks)
532 for (LandmarkMap::iterator iter=landmarks.begin(); iter!=landmarks.end(); ++iter)
534 lm << mPatientModelService->getLandmarkProperties()[iter->second.getUid()].getName();
537 QString msg = QString(
"Preparing to register [%1] containing the landmarks: [%2]").arg(name).arg(lm.join(
","));
551 for (
unsigned i=0; i<uids.size(); ++i)
553 QString uid = uids[i];
554 Vector3D p = M.coord(data.find(uid)->second.getCoord());
555 retval->InsertNextPoint(p.begin());
QString qstring_cast(const T &val)
void reportError(QString msg)
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.
void isLoadingSecond(QDomElement &root)
Emitted after the isLoading signal, to allow for structures that must be loaded after core structures...
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)
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 applyContinuousPatientRegistration(Transform3D rMpr_new, QString description)
virtual void applyPatientRegistration(Transform3D rMpr_new, QString description)
virtual void applyContinuousImage2ImageRegistration(Transform3D delta_pre_rMd, QString description)
virtual void applyImage2ImageRegistration(Transform3D delta_pre_rMd, QString description)
void isSaving(QDomElement &root)
xml storage is available
vtkSmartPointer< class vtkPoints > vtkPointsPtr