7 #include "PlusConfigure.h" 10 #include "igsioTrackedFrame.h" 13 #include "vtkDoubleArray.h" 16 #include "vtkMatrix4x4.h" 17 #include "vtkObjectFactory.h" 18 #include "vtkPoints.h" 19 #include "vtkIGSIOTrackedFrameList.h" 20 #include "vtkTransform.h" 21 #include "vtkIGSIOTransformRepository.h" 22 #include "vtkVariantArray.h" 24 #include "vtksys/SystemTools.hxx" 26 #include "vnl/vnl_cross.h" 68 this->Superclass::PrintSelf(os, indent);
69 os << indent <<
"Update time: " <<
UpdateTime.GetMTime() << std::endl;
70 os << indent <<
"Spacing: " << this->
Spacing[0] <<
" " << this->
Spacing[1] << std::endl;
75 os << indent <<
"Phantom to reference transform: " << std::endl;
81 os << indent <<
"TrackedFrameList:" << std::endl;
90 LOG_TRACE(
"vtkPlusBrachyStepperPhantomRegistrationAlgo::SetInputs");
103 LOG_TRACE(
"vtkPlusBrachyStepperPhantomRegistrationAlgo::GetRotationEncoderScale");
119 LOG_TRACE(
"vtkPlusBrachyStepperPhantomRegistrationAlgo::Update");
121 if (this->GetMTime() < this->
UpdateTime.GetMTime())
123 LOG_DEBUG(
"Rotation encoder calibration result is up-to-date!");
130 LOG_ERROR(
"Failed to perform calibration - tracked frame list is invalid");
144 std::vector<vtkSmartPointer<vtkPoints> > vectorOfWirePoints;
145 for (
unsigned int index = 0; index < this->
TrackedFrameList->GetNumberOfTrackedFrames(); ++index)
148 igsioTrackedFrame* trackedFrame = this->
TrackedFrameList->GetTrackedFrame(index);
150 if (trackedFrame->GetFiducialPointsCoordinatePx() == NULL)
152 LOG_ERROR(
"Unable to get segmented fiducial points from tracked frame - FiducialPointsCoordinatePx is NULL, frame is not yet segmented (position in the list: " << index <<
")!");
156 if (trackedFrame->GetFiducialPointsCoordinatePx()->GetNumberOfPoints() == 0)
158 LOG_DEBUG(
"Unable to get segmented fiducial points from tracked frame - couldn't segment image (position in the list: " << index <<
")!");
163 vtkSmartPointer<vtkPoints> pointset = vtkSmartPointer<vtkPoints>::New();
164 pointset->SetDataTypeToDouble();
165 pointset->InsertNextPoint(trackedFrame->GetFiducialPointsCoordinatePx()->GetPoint(3));
166 pointset->InsertNextPoint(trackedFrame->GetFiducialPointsCoordinatePx()->GetPoint(5));
167 pointset->InsertNextPoint(trackedFrame->GetFiducialPointsCoordinatePx()->GetPoint(2));
168 vectorOfWirePoints.push_back(pointset);
172 vnl_vector<double> rotationCenter3x1InMm(3, 0);
175 rotationCenter3x1InMm.put(2, 0);
178 const int totalNumberOfImages2ComputePtLnDist = vectorOfWirePoints.size();
180 if (totalNumberOfImages2ComputePtLnDist == 0)
182 LOG_ERROR(
"Failed to register phantom to reference. Probe distance calculation data is empty!");
187 vnl_vector<double> listOfPhantomToProbeVerticalDistanceInMm(totalNumberOfImages2ComputePtLnDist, 0);
188 vnl_vector<double> listOfPhantomToProbeHorizontalDistanceInMm(totalNumberOfImages2ComputePtLnDist, 0);
190 for (
int i = 0;
i < totalNumberOfImages2ComputePtLnDist;
i++)
193 vnl_vector<double> pointAInMm(3, 0);
194 pointAInMm.put(0, vectorOfWirePoints[
i]->GetPoint(0)[0] * this->Spacing[0]);
195 pointAInMm.put(1, vectorOfWirePoints[
i]->GetPoint(0)[1] * this->Spacing[1]);
196 pointAInMm.put(2, 0);
199 vnl_vector<double> pointBInMm(3, 0);
200 pointBInMm.put(0, vectorOfWirePoints[
i]->GetPoint(1)[0] * this->Spacing[0]);
201 pointBInMm.put(1, vectorOfWirePoints[
i]->GetPoint(1)[1] * this->Spacing[1]);
202 pointBInMm.put(2, 0);
205 vnl_vector<double> pointCInMm(3, 0);
206 pointCInMm.put(0, vectorOfWirePoints[
i]->GetPoint(2)[0] * this->Spacing[0]);
207 pointCInMm.put(1, vectorOfWirePoints[
i]->GetPoint(2)[1] * this->Spacing[1]);
208 pointCInMm.put(2, 0);
211 const vnl_vector<double> vectorRotationCenterToPointAInMm = pointAInMm - rotationCenter3x1InMm;
212 const vnl_vector<double> vectorRotationCenterToPointBInMm = pointBInMm - rotationCenter3x1InMm;
213 const vnl_vector<double> vectorRotationCenterToPointCInMm = pointCInMm - rotationCenter3x1InMm;
214 const vnl_vector<double> vectorPointAToPointBInMm = pointBInMm - pointAInMm;
215 const vnl_vector<double> vectorPointBToPointCInMm = pointCInMm - pointBInMm;
219 const double thisPhantomToProbeVerticalDistanceInMm = vnl_cross_3d(vectorRotationCenterToPointAInMm, vectorRotationCenterToPointBInMm).magnitude() / vectorPointAToPointBInMm.magnitude();
223 const double thisPhantomToProbeHorizontalDistanceInMm = vnl_cross_3d(vectorRotationCenterToPointBInMm, vectorRotationCenterToPointCInMm).magnitude() / vectorPointBToPointCInMm.magnitude();
226 listOfPhantomToProbeVerticalDistanceInMm.put(
i, thisPhantomToProbeVerticalDistanceInMm);
227 listOfPhantomToProbeHorizontalDistanceInMm.put(
i, thisPhantomToProbeHorizontalDistanceInMm);
230 double wire6ToProbeDistanceInMm[2] = { listOfPhantomToProbeHorizontalDistanceInMm.mean(), listOfPhantomToProbeVerticalDistanceInMm.mean() };
231 double phantomToReferenceDistanceInMm[3] = { this->
NWires[1].GetWires()[2].EndPointFront[0] + wire6ToProbeDistanceInMm[0], this->
NWires[1].GetWires()[2].EndPointFront[1] + wire6ToProbeDistanceInMm[1], 0 };
233 LOG_INFO(
"Phantom to probe distance (mm): " << phantomToReferenceDistanceInMm[0] <<
" " << phantomToReferenceDistanceInMm[1]);
235 vtkSmartPointer<vtkTransform> phantomToReferenceTransform = vtkSmartPointer<vtkTransform>::New();
236 phantomToReferenceTransform->Identity();
237 phantomToReferenceTransform->Translate(phantomToReferenceDistanceInMm);
238 phantomToReferenceTransform->Inverse();
248 this->
TransformRepository->SetTransformDate(phantomToReferenceTransformName, vtkIGSIOAccurateTimer::GetInstance()->GetDateAndTimeString().c_str());
253 LOG_INFO(
"Transform repository object is NULL, cannot save results into it");
264 LOG_TRACE(
"vtkPlusBrachyStepperPhantomRegistrationAlgo::ReadConfiguration");
266 XML_FIND_NESTED_ELEMENT_REQUIRED(phantomRegistrationElement, aConfig,
"vtkPlusBrachyStepperPhantomRegistrationAlgo");
vtkIGSIOTransformRepository * TransformRepository
vtkPlusBrachyStepperPhantomRegistrationAlgo()
virtual PlusStatus Update()
virtual ~vtkPlusBrachyStepperPhantomRegistrationAlgo()
virtual void SetSpacing(double, double)
virtual void SetCenterOfRotationPx(double, double)
void SetTransformRepository(vtkIGSIOTransformRepository *)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
vtkMatrix4x4 * PhantomToReferenceTransformMatrix
double CenterOfRotationPx[2]
virtual void SetTrackedFrameList(vtkIGSIOTrackedFrameList *)
vtkCxxSetObjectMacro(vtkPlusBrachyStepperPhantomRegistrationAlgo, TransformRepository, vtkIGSIOTransformRepository)
std::vector< PlusNWire > NWires
virtual void SetInputs(vtkIGSIOTrackedFrameList *trackedFrameList, double spacing[2], double centerOfRotationPx[2], vtkIGSIOTransformRepository *transformRepository, const std::vector< PlusNWire > &nWires)
vtkIGSIOTrackedFrameList * TrackedFrameList
vtkStandardNewMacro(vtkPlusBrachyStepperPhantomRegistrationAlgo)
char * PhantomCoordinateFrame
char * ReferenceCoordinateFrame
PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
virtual PlusStatus GetPhantomToReferenceTransformMatrix(vtkMatrix4x4 *phantomToReferenceTransform)
Phantom registration algorithm for image to probe calibration with brachy stepper.