7 #include "basicRegistration/SPointListRegistration.hpp" 9 #include <fwCom/Signal.hxx> 10 #include <fwCom/Slots.hxx> 12 #include <fwData/Composite.hpp> 13 #include <fwData/Mesh.hpp> 14 #include <fwData/PointList.hpp> 15 #include <fwData/String.hpp> 16 #include <fwData/TransformationMatrix3D.hpp> 18 #include <fwDataTools/fieldHelper/Image.hpp> 20 #include <fwGui/dialog/MessageDialog.hpp> 22 #include <fwServices/macros.hpp> 24 #include <vtkLandmarkTransform.h> 25 #include <vtkMatrix4x4.h> 26 #include <vtkPoints.h> 27 #include <vtkSmartPointer.h> 34 const ::fwCom::Slots::SlotKeyType SPointListRegistration::s_CHANGE_MODE =
"changeMode";
35 static const ::fwCom::Signals::SignalKeyType s_ERROR_COMPUTED_SIG =
"errorComputed";
37 SPointListRegistration::SPointListRegistration() :
38 m_registrationMode(RIGID)
40 newSignal<ErrorComputedSignalType>(s_ERROR_COMPUTED_SIG);
41 newSlot(s_CHANGE_MODE, &SPointListRegistration::changeMode,
this);
46 SPointListRegistration::~SPointListRegistration()
52 void SPointListRegistration::configuring()
55 const auto config = configTree.get_child_optional(
"config.<xmlattr>");
59 const std::string mode = config->get< std::string >(
"mode",
"rigid");
63 m_registrationMode = RIGID;
65 else if(mode ==
"similarity")
67 m_registrationMode = SIMILARITY;
69 else if(mode ==
"affine")
71 m_registrationMode = AFFINE;
75 SLM_ERROR(
"Unknown registration mode: '" + mode +
"', it must be 'rigid', 'similarity' or 'affine'." 76 " Defaulting to 'rigid'.")
81 m_registrationMode = RIGID;
87 void SPointListRegistration::starting()
93 void SPointListRegistration::stopping()
101 ::fwData::PointList::sptr registeredPL = this->getInOut< ::fwData::PointList >(
"registeredPL");
102 ::fwData::PointList::sptr referencePL = this->getInOut< ::fwData::PointList >(
"referencePL");
103 ::fwData::TransformationMatrix3D::sptr matrix = this->getInOut< ::fwData::TransformationMatrix3D >(
"output");
105 if( registeredPL->getPoints().size() >= 3 &&
106 registeredPL->getPoints().size() == referencePL->getPoints().size() )
108 vtkSmartPointer<vtkLandmarkTransform> landmarkTransform = vtkSmartPointer<vtkLandmarkTransform>::New();
110 vtkSmartPointer<vtkPoints> sourcePts = vtkSmartPointer<vtkPoints>::New();
111 vtkSmartPointer<vtkPoints> targetPts = vtkSmartPointer<vtkPoints>::New();
113 const auto& firstPoint = referencePL->getPoints()[0];
119 for( ::fwData::Point::sptr pointRef : referencePL->getPoints() )
121 const std::string& labelRef =
124 for( ::fwData::Point::sptr pointReg : registeredPL->getPoints() )
126 const std::string& labelReg =
129 if(labelRef == labelReg)
131 auto coord = pointRef->getCoord();
132 sourcePts->InsertNextPoint(coord[0], coord[1], coord[2]);
137 "referencePL : " << pointRef->getCoord()[0] <<
" " << pointRef->getCoord()[1] <<
" " <<
138 pointRef->getCoord()[2] );
140 coord = pointReg->getCoord();
141 targetPts->InsertNextPoint(coord[0], coord[1], coord[2]);
145 "registeredPL : " << pointReg->getCoord()[0] <<
" " << pointReg->getCoord()[1] <<
" " <<
146 pointReg->getCoord()[2] );
154 for(
const auto& refPoint : referencePL->getPoints())
156 const auto& coords = refPoint->getCoord();
157 sourcePts->InsertNextPoint(coords[0], coords[1], coords[2]);
160 for(
const auto& regPoint : registeredPL->getPoints())
162 const auto& coords = regPoint->getCoord();
163 targetPts->InsertNextPoint(coords[0], coords[1], coords[2]);
167 landmarkTransform->SetSourceLandmarks(sourcePts);
168 landmarkTransform->SetTargetLandmarks(targetPts);
170 if(m_registrationMode == AFFINE)
172 landmarkTransform->SetModeToAffine();
174 else if(m_registrationMode == SIMILARITY)
176 landmarkTransform->SetModeToSimilarity();
180 landmarkTransform->SetModeToRigidBody();
183 landmarkTransform->Update();
186 vtkSmartPointer<vtkMatrix4x4> m = landmarkTransform->GetMatrix();
188 for(std::uint8_t l = 0; l < 4; ++l)
190 for(std::uint8_t c = 0; c < 4; ++c)
192 matrix->setCoefficient(l, c, m->GetElement(l, c));
197 double errorValue = 0.;
199 for(vtkIdType i = 0; i < sourcePts->GetNumberOfPoints(); ++i)
202 sourcePts->GetPoint(i, p1);
204 targetPts->GetPoint(i, p2);
207 double p2H[4] = { 1., 1., 1., 1.};
208 std::copy(std::begin(p2), std::end(p2), std::begin(p2H));
212 m->MultiplyPoint(p2H, newP);
214 errorValue += std::sqrt(((p1[0] - newP[0]) * (p1[0] - newP[0])) +
215 ((p1[1] - newP[1]) * (p1[1] - newP[1])) +
216 ((p1[2] - newP[2]) * (p1[2] - newP[2])));
219 errorValue /= sourcePts->GetNumberOfPoints();
223 this->signal<ErrorComputedSignalType>(s_ERROR_COMPUTED_SIG)->asyncEmit(errorValue);
234 if(registeredPL->getPoints().size() < 3)
237 "You must enter 3 or more points for the registration to work.",
238 ::fwGui::dialog::IMessageDialog::WARNING);
242 std::string msg =
"The pointlists doesn't have the same number of points : ";
243 msg += std::to_string(registeredPL->getPoints().size()) +
" != " + std::to_string(
244 referencePL->getPoints().size());
252 void SPointListRegistration::updating()
254 const ::fwCore::HiResClock::HiResClockType timestamp = ::fwCore::HiResClock::getTimeInMilliSec();
255 this->computeRegistration(timestamp);
260 void SPointListRegistration::swapping()
269 void SPointListRegistration::changeMode(std::string _value)
271 if(_value ==
"RIGID")
273 m_registrationMode = RIGID;
275 else if( _value ==
"SIMILARITY")
277 m_registrationMode = SIMILARITY;
279 else if(_value ==
"AFFINE")
281 m_registrationMode = AFFINE;
285 SLM_ERROR(
"key "+ _value +
" is not handled.");
Class allowing to block a Connection.
static FWGUI_API IMessageDialog::Buttons showMessageDialog(const std::string &title, const std::string &message,::fwGui::dialog::IMessageDialog::Icons icon=INFO)
The namespace basicRegistration contains services to perfom a basic registration between images and m...
#define OSLM_TRACE(message)
double HiResClockType
Type returned by HiResClock Functions.
VISUVTKADAPTOR_API void starting() override
Initialize the service activity.
T & value() noexcept
Get the value (mutable version).
UpdateSlotType::sptr m_slotUpdate
Slot to call update method.
#define SLM_ERROR(message)
This interface defines registerer service API. Must be implemented for services that register objects...
VISUVTKADAPTOR_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
Register a point list against a reference point list. Each point in the list to register is matched w...
This class contains an std::string value.
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.