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)
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");
360 delta = this->performLandmarkRegistration(p_moving_r, p_fixed_r, &ok);
361 idString = QString(
"Image to Image Landmark");
366 reportError(
"I-I Landmark registration: Failed to register: [" +
qstring_cast(p_moving_r->GetNumberOfPoints()) +
"p], "+ movingImage->getName());
373 std::vector<Vector3D> RegistrationImplService::convertVtkPointsToPoints(
vtkPointsPtr base)
375 std::vector<Vector3D> retval;
377 for (
int i=0; i<base->GetNumberOfPoints(); ++i)
393 if (source->GetNumberOfPoints() < 3)
395 return Transform3D::Identity();
399 landmarktransform->SetSourceLandmarks(source);
400 landmarktransform->SetTargetLandmarks(target);
401 landmarktransform->SetModeToRigidBody();
404 landmarktransform->Update();
406 Transform3D tar_M_src(landmarktransform->GetMatrix());
408 if (QString::number(tar_M_src(0,0))==
"nan")
410 return Transform3D::Identity();
419 this->performImage2ImageRegistration(dMd, description);
424 this->performImage2ImageRegistration(dMd, description,
true);
427 void RegistrationImplService::performImage2ImageRegistration(
Transform3D dMd, QString description,
bool temporaryRegistration)
429 RegistrationTransform regTrans(dMd, QDateTime::currentDateTime(), description, temporaryRegistration);
430 regTrans.
mFixed = mFixedData;
431 regTrans.
mMoving = mMovingData;
433 this->updateRegistration_rMd(mLastRegistrationTime, regTrans, this->
getMovingData());
436 if(!temporaryRegistration)
437 reportSuccess(QString(
"Image registration [%1] has been performed on %2").arg(description).arg(regTrans.
mMoving) );
442 this->performPatientRegistration(rMpr_new, description);
447 this->performPatientRegistration(rMpr_new, description,
true);
450 void RegistrationImplService::performPatientRegistration(
Transform3D rMpr_new, QString description,
bool temporaryRegistration)
452 RegistrationTransform regTrans(rMpr_new, QDateTime::currentDateTime(), description, temporaryRegistration);
453 regTrans.
mFixed = mFixedData;
455 mPatientModelService->updateRegistration_rMpr(mLastRegistrationTime, regTrans);
458 if(!temporaryRegistration)
459 reportSuccess(QString(
"Patient registration [%1] has been performed.").arg(description));
471 applicator.updateRegistration(oldTime, dMd);
473 bool silent = dMd.
mTemp;
475 mPatientModelService->autoSave();
487 Transform3D rMpr = mPatientModelService->get_rMpr();
500 QString description(
"Patient Orientation");
513 std::map<QString,DataPtr> data = mPatientModelService->getDatas();
515 for (std::map<QString,DataPtr>::iterator iter = data.begin(); iter!=data.end(); ++iter)
517 DataPtr current = iter->second;
519 newTransform.
mValue = regTrans.
mValue * current->get_rMd();
520 current->get_rMd_History()->addOrUpdateRegistration(oldTime, newTransform);
522 report(
"Updated registration of data " + current->getName());
523 std::cout <<
"rMd_new\n" << newTransform.
mValue << std::endl;
531 void RegistrationImplService::writePreLandmarkRegistration(QString name,
LandmarkMap landmarks)
534 for (LandmarkMap::iterator iter=landmarks.begin(); iter!=landmarks.end(); ++iter)
536 lm << mPatientModelService->getLandmarkProperties()[iter->second.getUid()].getName();
539 QString msg = QString(
"Preparing to register [%1] containing the landmarks: [%2]").arg(name).arg(lm.join(
","));
553 for (
unsigned i=0; i<uids.size(); ++i)
555 QString uid = uids[i];
556 Vector3D p = M.coord(data.find(uid)->second.getCoord());
557 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
XMLNodeAdder descend(QString path)
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 addImage2ImageRegistration(Transform3D dMd, QString description)
virtual void doImageRegistration(bool translationOnly)
vtkSmartPointer< vtkPoints > vtkPointsPtr
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 void updateImage2ImageRegistration(Transform3D dMd, QString description)
virtual DataPtr getFixedData()
virtual DataPtr getMovingData()
boost::shared_ptr< class Data > DataPtr
virtual void addPatientRegistration(Transform3D rMpr_new, QString description)
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
XMLNodeParser descend(QString path)
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.
virtual void updatePatientRegistration(Transform3D rMpr_new, QString description)
std::map< QString, class Landmark > LandmarkMap
Always provides a PatientModelService.
void isSaving(QDomElement &root)
xml storage is available
Namespace for all CustusX production code.