double ManualImage2ImageRegistrationWidget::getAccuracy(QString uid) { DataPtr fixedData = mServices->registration()->getFixedData(); if (!fixedData) return 1000.0; DataPtr movingData = mServices->registration()->getMovingData(); if (!movingData) return 1000.0; Landmark masterLandmark = fixedData->getLandmarks()->getLandmarks()[uid]; Landmark targetLandmark = movingData->getLandmarks()->getLandmarks()[uid]; if (masterLandmark.getUid().isEmpty() || targetLandmark.getUid().isEmpty()) return 1000.0; Vector3D p_master_master = masterLandmark.getCoord(); Vector3D p_target_target = targetLandmark.getCoord(); Transform3D rMmaster = fixedData->get_rMd(); Transform3D rMtarget = movingData->get_rMd(); Vector3D p_target_r = rMtarget.coord(p_target_target); Vector3D p_master_r = rMmaster.coord(p_master_master); double targetPoint[3]; double masterPoint[3]; targetPoint[0] = p_target_r[0]; targetPoint[1] = p_target_r[1]; targetPoint[2] = p_target_r[2]; masterPoint[0] = p_master_r[0]; masterPoint[1] = p_master_r[1]; masterPoint[2] = p_master_r[2]; return (vtkMath::Distance2BetweenPoints(targetPoint, masterPoint)); }
void RegistrationImplService::doPatientRegistration() { DataPtr fixedImage = this->getFixedData(); if(!fixedImage) { reportError("The fixed data is not set, cannot do patient registration!"); return; } LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks(); LandmarkMap toolLandmarks = mPatientModelService->getPatientLandmarks()->getLandmarks(); this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks()); this->writePreLandmarkRegistration("physical", toolLandmarks); std::vector<QString> landmarks = this->getUsableLandmarks(fixedLandmarks, toolLandmarks); vtkPointsPtr p_ref = this->convertTovtkPoints(landmarks, fixedLandmarks, fixedImage->get_rMd()); vtkPointsPtr p_pr = this->convertTovtkPoints(landmarks, toolLandmarks, Transform3D::Identity()); // ignore if too few data. if (p_ref->GetNumberOfPoints() < 3) return; bool ok = false; Transform3D rMpr = this->performLandmarkRegistration(p_pr, p_ref, &ok); if (!ok) { reportError("P-I Landmark registration: Failed to register: [" + qstring_cast(p_pr->GetNumberOfPoints()) + "p]"); return; } this->applyPatientRegistration(rMpr, "Patient Landmark"); }
/** Return transform from target space to reference space * */ Transform3D ImageLandmarksWidget::getTargetTransform() const { DataPtr image = this->getCurrentData(); if (!image) return Transform3D::Identity(); return image->get_rMd(); }
std::vector<Vector3D> CustomMetric::getPointCloud() const { std::vector<Vector3D> retval; DataPtr model = this->getModel(); std::vector<Transform3D> pos = this->calculateOrientations(); std::vector<Vector3D> cloud; Transform3D rrMd; if (model) { rrMd = model->get_rMd(); cloud = model->getPointCloud(); } else { cloud.push_back(Vector3D::Zero()); rrMd = Transform3D::Identity(); } for (unsigned i=0; i<pos.size(); ++i) { Transform3D rMd = pos[i] * rrMd; for (unsigned j=0; j<cloud.size(); ++j) { Vector3D p_r = rMd.coord(cloud[j]); retval.push_back(p_r); } } return retval; }
/** Apply the transform from the parent frame to the imported data. * */ void ImportDataDialog::importParentTransform() { if (!mTransformFromParentFrameCheckBox->isChecked()) return; if(!mData) return; DataPtr parent = mPatientModelService->getData(mData->getParentSpace()); if (!parent) return; mData->get_rMd_History()->setRegistration(parent->get_rMd()); report("Assigned rMd from data [" + parent->getName() + "] to data [" + mData->getName() + "]"); }
/**\brief Identical to doFastRegistration_Orientation(), except data does not move. * * When applying a new transform to the patient orientation, all data is moved * the the inverse of that value, thus giving a net zero change along the path * pr...d_i. * */ void RegistrationImplService::applyPatientOrientation(const Transform3D& tMtm, const Transform3D& prMt) { Transform3D rMpr = mPatientModelService->get_rMpr(); //create a marked(m) space tm, which is related to tool space (t) as follows: //the tool is defined in DICOM space such that //the tool points toward the patients feet and the spheres faces the same //direction as the nose Transform3D tMpr = prMt.inv(); // this is the new patient registration: Transform3D tmMpr = tMtm * tMpr; // the change in pat reg becomes: Transform3D F = tmMpr * rMpr.inv(); QString description("Patient Orientation"); QDateTime oldTime = this->getLastRegistrationTime(); // time of previous reg this->applyPatientRegistration(tmMpr, description); // now apply the inverse of F to all data, // thus ensuring the total path from pr to d_i is unchanged: Transform3D delta_pre_rMd = F; // use the same registration time as generated in the applyPatientRegistration() above: RegistrationTransform regTrans(delta_pre_rMd, this->getLastRegistrationTime(), description); std::map<QString,DataPtr> data = mPatientModelService->getData(); // update the transform on all target data: for (std::map<QString,DataPtr>::iterator iter = data.begin(); iter!=data.end(); ++iter) { DataPtr current = iter->second; RegistrationTransform newTransform = regTrans; newTransform.mValue = regTrans.mValue * current->get_rMd(); current->get_rMd_History()->updateRegistration(oldTime, newTransform); report("Updated registration of data " + current->getName()); std::cout << "rMd_new\n" << newTransform.mValue << std::endl; } this->setLastRegistrationTime(regTrans.mTimestamp); reportSuccess("Patient Orientation has been performed"); }
void ImageLandmarksWidget::editLandmarkButtonClickedSlot() { PickerRepPtr PickerRep = this->getPickerRep(); if (!PickerRep) { reportError("Need a 3D view to edit landmarks."); return; } DataPtr image = this->getCurrentData(); if (!image) return; QString uid = mActiveLandmark; Vector3D pos_r = PickerRep->getPosition(); Vector3D pos_d = image->get_rMd().inv().coord(pos_r); image->getLandmarks()->setLandmark(Landmark(uid, pos_d)); this->activateLandmark(this->getNextLandmark()); }
double LandmarkRegistrationWidget::getAccuracy(QString uid) { DataPtr fixedData = mServices->registration()->getFixedData(); if (!fixedData) return 1000.0; Landmark masterLandmark = fixedData->getLandmarks()->getLandmarks()[uid]; Landmark targetLandmark = this->getTargetLandmarks()[uid]; if (masterLandmark.getUid().isEmpty() || targetLandmark.getUid().isEmpty()) return 1000.0; Vector3D p_master_master = masterLandmark.getCoord(); Vector3D p_target_target = targetLandmark.getCoord(); Transform3D rMmaster = fixedData->get_rMd(); Transform3D rMtarget = this->getTargetTransform(); Vector3D p_target_r = rMtarget.coord(p_target_target); Vector3D p_master_r = rMmaster.coord(p_master_master); return (p_target_r - p_master_r).length(); }
void RegistrationImplService::doFastRegistration_Translation() { DataPtr fixedImage = this->getFixedData(); if(!fixedImage) { reportError("The fixed data is not set, cannot do image registration!"); return; } LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks(); LandmarkMap toolLandmarks = mPatientModelService->getPatientLandmarks()->getLandmarks(); this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks()); this->writePreLandmarkRegistration("physical", toolLandmarks); std::vector<QString> landmarks = this->getUsableLandmarks(fixedLandmarks, toolLandmarks); Transform3D rMd = fixedImage->get_rMd(); Transform3D rMpr_old = mPatientModelService->get_rMpr(); std::vector<Vector3D> p_pr_old = this->convertAndTransformToPoints(landmarks, fixedLandmarks, rMpr_old.inv()*rMd); std::vector<Vector3D> p_pr_new = this->convertAndTransformToPoints(landmarks, toolLandmarks, Transform3D::Identity()); // ignore if too few data. if (p_pr_old.size() < 1) return; LandmarkTranslationRegistration landmarkTransReg; bool ok = false; Transform3D pr_oldMpr_new = landmarkTransReg.registerPoints(p_pr_old, p_pr_new, &ok); if (!ok) { reportError("Fast translation registration: Failed to register: [" + qstring_cast(p_pr_old.size()) + "points]"); return; } this->applyPatientRegistration(rMpr_old*pr_oldMpr_new, "Fast Translation"); }
void RegistrationImplService::doImageRegistration(bool translationOnly) { //check that the fixed data is set DataPtr fixedImage = this->getFixedData(); if(!fixedImage) { reportError("The fixed data is not set, cannot do landmark image registration!"); return; } //check that the moving data is set DataPtr movingImage = this->getMovingData(); if(!movingImage) { reportError("The moving data is not set, cannot do landmark image registration!"); return; } // ignore self-registration, this gives no effect bestcase, buggy behaviour worstcase (has been observed) if(movingImage==fixedImage) { reportError("The moving and fixed are equal, ignoring landmark image registration!"); return; } LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks(); LandmarkMap imageLandmarks = movingImage->getLandmarks()->getLandmarks(); this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks()); this->writePreLandmarkRegistration(movingImage->getName(), movingImage->getLandmarks()->getLandmarks()); std::vector<QString> landmarks = getUsableLandmarks(fixedLandmarks, imageLandmarks); vtkPointsPtr p_fixed_r = convertTovtkPoints(landmarks, fixedLandmarks, fixedImage->get_rMd()); vtkPointsPtr p_moving_r = convertTovtkPoints(landmarks, imageLandmarks, movingImage->get_rMd()); int minNumberOfPoints = 3; if (translationOnly) minNumberOfPoints = 1; // ignore if too few data. if (p_fixed_r->GetNumberOfPoints() < minNumberOfPoints) { reportError( QString("Found %1 corresponding landmarks, need %2, cannot do landmark image registration!") .arg(p_fixed_r->GetNumberOfPoints()) .arg(minNumberOfPoints) ); return; } bool ok = false; QString idString; Transform3D delta; if (translationOnly) { LandmarkTranslationRegistration landmarkTransReg; delta = landmarkTransReg.registerPoints(convertVtkPointsToPoints(p_fixed_r), convertVtkPointsToPoints(p_moving_r), &ok); idString = QString("Image to Image Landmark Translation"); } else { Transform3D rMd; delta = this->performLandmarkRegistration(p_moving_r, p_fixed_r, &ok); idString = QString("Image to Image Landmark"); } if (!ok) { reportError("I-I Landmark registration: Failed to register: [" + qstring_cast(p_moving_r->GetNumberOfPoints()) + "p], "+ movingImage->getName()); return; } this->applyImage2ImageRegistration(delta, idString); }