14 #include <ctkPluginContext.h>
15 #include <ctkServiceTracker.h>
16 #include <vtkPoints.h>
17 #include <vtkLandmarkTransform.h>
18 #include <vtkMatrix4x4.h>
37 mLastRegistrationTime(QDateTime::currentDateTime()),
51 void RegistrationImplService::duringSavePatientSlot(QDomElement& node)
54 QDomElement managerNode = root.descend(
"managers").node().toElement();
55 this->addXml(managerNode);
58 void RegistrationImplService::duringLoadPatientSlot(QDomElement& node)
60 XMLNodeParser root(node);
61 QDomElement registrationManager = root.descend(
"managers/registrationManager").node().toElement();
62 if (!registrationManager.isNull())
63 this->parseXml(registrationManager);
66 void RegistrationImplService::addXml(QDomNode& parentNode)
68 QDomDocument doc = parentNode.ownerDocument();
69 QDomElement base = doc.createElement(
"registrationManager");
70 parentNode.appendChild(base);
72 QDomElement fixedDataNode = doc.createElement(
"fixedDataUid");
76 fixedDataNode.appendChild(doc.createTextNode(fixedData->getUid()));
78 base.appendChild(fixedDataNode);
80 QDomElement movingDataNode = doc.createElement(
"movingDataUid");
84 movingDataNode.appendChild(doc.createTextNode(movingData->getUid()));
86 base.appendChild(movingDataNode);
89 void RegistrationImplService::parseXml(QDomNode& dataNode)
91 QString fixedData = dataNode.namedItem(
"fixedDataUid").toElement().text();
94 QString movingData = dataNode.namedItem(
"movingDataUid").toElement().text();
98 void RegistrationImplService::clearSlot()
116 if (uid==mMovingData)
132 return mPatientModelService->getData(mMovingData);
137 return mPatientModelService->getData(mFixedData);
142 return mLastRegistrationTime;
147 mLastRegistrationTime = time;
156 reportError(
"The fixed data is not set, cannot do patient registration!");
159 LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
160 LandmarkMap toolLandmarks = mPatientModelService->getPatientLandmarks()->getLandmarks();
162 this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
163 this->writePreLandmarkRegistration(
"physical", toolLandmarks);
165 std::vector<QString> landmarks = this->getUsableLandmarks(fixedLandmarks, toolLandmarks);
167 vtkPointsPtr p_ref = this->convertTovtkPoints(landmarks, fixedLandmarks, fixedImage->get_rMd());
168 vtkPointsPtr p_pr = this->convertTovtkPoints(landmarks, toolLandmarks, Transform3D::Identity());
171 if (p_ref->GetNumberOfPoints() < 3)
175 Transform3D rMpr = this->performLandmarkRegistration(p_pr, p_ref, &ok);
178 reportError(
"P-I Landmark registration: Failed to register: [" +
qstring_cast(p_pr->GetNumberOfPoints()) +
"p]");
190 reportError(
"The fixed data is not set, cannot do image registration!");
194 LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
195 LandmarkMap toolLandmarks = mPatientModelService->getPatientLandmarks()->getLandmarks();
197 this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
198 this->writePreLandmarkRegistration(
"physical", toolLandmarks);
200 std::vector<QString> landmarks = this->getUsableLandmarks(fixedLandmarks, toolLandmarks);
203 Transform3D rMpr_old = mPatientModelService->get_rMpr();
204 std::vector<Vector3D> p_pr_old = this->convertAndTransformToPoints(landmarks, fixedLandmarks, rMpr_old.inv()*rMd);
205 std::vector<Vector3D> p_pr_new = this->convertAndTransformToPoints(landmarks, toolLandmarks, Transform3D::Identity());
208 if (p_pr_old.size() < 1)
216 reportError(
"Fast translation registration: Failed to register: [" +
qstring_cast(p_pr_old.size()) +
"points]");
245 std::vector<Vector3D> RegistrationImplService::convertAndTransformToPoints(
const std::vector<QString>& uids,
const LandmarkMap& data,
Transform3D M)
247 std::vector<Vector3D> retval;
249 for (
unsigned i=0; i<uids.size(); ++i)
251 QString uid = uids[i];
252 Vector3D p = M.coord(data.find(uid)->second.getCoord());
262 std::vector<QString> RegistrationImplService::getUsableLandmarks(
const LandmarkMap& data_a,
const LandmarkMap& data_b)
264 std::vector<QString> retval;
265 std::map<QString, LandmarkProperty> props = mPatientModelService->getLandmarkProperties();
266 std::map<QString, LandmarkProperty>::iterator iter;
268 for (iter=props.begin(); iter!=props.end(); ++iter)
270 QString uid = iter->first;
271 if (data_a.count(uid) && data_b.count(uid) && iter->second.getActive())
272 retval.push_back(uid);
283 reportError(
"The fixed data is not set, cannot do landmark image registration!");
291 reportError(
"The moving data is not set, cannot do landmark image registration!");
296 if(movingImage==fixedImage)
298 reportError(
"The moving and fixed are equal, ignoring landmark image registration!");
302 LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
303 LandmarkMap imageLandmarks = movingImage->getLandmarks()->getLandmarks();
305 this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
306 this->writePreLandmarkRegistration(movingImage->getName(), movingImage->getLandmarks()->getLandmarks());
308 std::vector<QString> landmarks = getUsableLandmarks(fixedLandmarks, imageLandmarks);
309 vtkPointsPtr p_fixed_r = convertTovtkPoints(landmarks, fixedLandmarks, fixedImage->get_rMd());
310 vtkPointsPtr p_moving_r = convertTovtkPoints(landmarks, imageLandmarks, movingImage->get_rMd());
312 int minNumberOfPoints = 3;
314 minNumberOfPoints = 1;
317 if (p_fixed_r->GetNumberOfPoints() < minNumberOfPoints)
320 QString(
"Found %1 corresponding landmarks, need %2, cannot do landmark image registration!")
321 .arg(p_fixed_r->GetNumberOfPoints())
322 .arg(minNumberOfPoints)
334 delta = landmarkTransReg.
registerPoints(convertVtkPointsToPoints(p_fixed_r), convertVtkPointsToPoints(p_moving_r), &ok);
335 idString = QString(
"Image to Image Landmark Translation");
339 delta = this->performLandmarkRegistration(p_moving_r, p_fixed_r, &ok);
340 idString = QString(
"Image to Image Landmark");
345 reportError(
"I-I Landmark registration: Failed to register: [" +
qstring_cast(p_moving_r->GetNumberOfPoints()) +
"p], "+ movingImage->getName());
352 std::vector<Vector3D> RegistrationImplService::convertVtkPointsToPoints(
vtkPointsPtr base)
354 std::vector<Vector3D> retval;
356 for (
int i=0; i<base->GetNumberOfPoints(); ++i)
372 if (source->GetNumberOfPoints() < 3)
374 return Transform3D::Identity();
378 landmarktransform->SetSourceLandmarks(source);
379 landmarktransform->SetTargetLandmarks(target);
380 landmarktransform->SetModeToRigidBody();
383 landmarktransform->Update();
385 Transform3D tar_M_src(landmarktransform->GetMatrix());
387 if (QString::number(tar_M_src(0,0))==
"nan")
389 return Transform3D::Identity();
398 this->performImage2ImageRegistration(dMd, description);
403 this->performImage2ImageRegistration(dMd, description,
true);
406 void RegistrationImplService::performImage2ImageRegistration(
Transform3D dMd, QString description,
bool temporaryRegistration)
408 RegistrationTransform regTrans(dMd, QDateTime::currentDateTime(), description, temporaryRegistration);
409 regTrans.mFixed = mFixedData;
410 regTrans.mMoving = mMovingData;
412 this->updateRegistration_rMd(mLastRegistrationTime, regTrans, this->
getMovingData());
414 mLastRegistrationTime = regTrans.mTimestamp;
415 if(!temporaryRegistration)
416 reportSuccess(QString(
"Image registration [%1] has been performed on %2").arg(description).arg(regTrans.mMoving) );
421 this->performPatientRegistration(rMpr_new, description);
426 this->performPatientRegistration(rMpr_new, description,
true);
429 void RegistrationImplService::performPatientRegistration(
Transform3D rMpr_new, QString description,
bool temporaryRegistration)
431 RegistrationTransform regTrans(rMpr_new, QDateTime::currentDateTime(), description, temporaryRegistration);
432 regTrans.mFixed = mFixedData;
434 mPatientModelService->updateRegistration_rMpr(mLastRegistrationTime, regTrans);
436 mLastRegistrationTime = regTrans.mTimestamp;
437 if(!temporaryRegistration)
438 reportSuccess(QString(
"Patient registration [%1] has been performed.").arg(description));
446 void RegistrationImplService::updateRegistration_rMd(QDateTime oldTime, RegistrationTransform dMd,
DataPtr data)
448 RegistrationApplicator applicator(mPatientModelService->getDatas());
449 dMd.mMoving = data->getUid();
450 applicator.updateRegistration(oldTime, dMd);
452 bool silent = dMd.mTemp;
454 mPatientModelService->autoSave();
466 Transform3D rMpr = mPatientModelService->get_rMpr();
479 QString description(
"Patient Orientation");
492 std::map<QString,DataPtr> data = mPatientModelService->getDatas();
494 for (std::map<QString,DataPtr>::iterator iter = data.begin(); iter!=data.end(); ++iter)
496 DataPtr current = iter->second;
498 newTransform.
mValue = regTrans.
mValue * current->get_rMd();
499 current->get_rMd_History()->addOrUpdateRegistration(oldTime, newTransform);
501 report(
"Updated registration of data " + current->getName());
502 std::cout <<
"rMd_new\n" << newTransform.
mValue << std::endl;
510 void RegistrationImplService::writePreLandmarkRegistration(QString name,
LandmarkMap landmarks)
513 for (LandmarkMap::iterator iter=landmarks.begin(); iter!=landmarks.end(); ++iter)
515 lm << mPatientModelService->getLandmarkProperties()[iter->second.getUid()].getName();
518 QString msg = QString(
"Preparing to register [%1] containing the landmarks: [%2]").arg(name).arg(lm.join(
","));
532 for (
unsigned i=0; i<uids.size(); ++i)
534 QString uid = uids[i];
535 Vector3D p = M.coord(data.find(uid)->second.getCoord());
536 retval->InsertNextPoint(p.begin());