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)
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());
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);
437 if(!temporaryRegistration)
438 reportSuccess(QString(
"Patient registration [%1] has been performed.").arg(description));
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());
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.