Commit 10ee10300e4b7e698ab4e892bc519f1cbec35b53

Authored by okahilak
Committed by GitHub
1 parent 9c40a251
Exists in master

MOD: Compute median over multiple tracker samples in object calibration (#342)

- This patch does not change the logic of what is done with the tracker
  samples in OnGetObjectFiducials function. However, maybe the logic
  indeed should be changed at some point; add a few comments to the
  code for the future reader of the code to perhaps grasp more easily
  what is done there.
invesalius/constants.py
... ... @@ -660,7 +660,7 @@ BOOLEAN_XOR = 4
660 660 MARKER_COLOUR = (1.0, 1.0, 0.)
661 661 MARKER_SIZE = 2
662 662  
663   -FIDUCIAL_REGISTRATION_TRACKER_SAMPLES = 10
  663 +CALIBRATION_TRACKER_SAMPLES = 10
664 664 FIDUCIAL_REGISTRATION_ERROR_THRESHOLD = 3.0
665 665  
666 666 SELECT = 0
... ...
invesalius/gui/dialogs.py
... ... @@ -3296,7 +3296,7 @@ class ObjectCalibrationDialog(wx.Dialog):
3296 3296 choice_ref = wx.ComboBox(self, -1, "", size=wx.Size(90, 23),
3297 3297 choices=const.REF_MODE, style=wx.CB_DROPDOWN | wx.CB_READONLY)
3298 3298 choice_ref.SetToolTip(tooltip)
3299   - choice_ref.Bind(wx.EVT_COMBOBOX, self.OnChoiceRefMode)
  3299 + choice_ref.Bind(wx.EVT_COMBOBOX, self.OnChooseReferenceMode)
3300 3300 choice_ref.SetSelection(1)
3301 3301 choice_ref.Enable(1)
3302 3302 if self.tracker_id == const.PATRIOT or self.tracker_id == const.ISOTRAKII:
... ... @@ -3396,7 +3396,7 @@ class ObjectCalibrationDialog(wx.Dialog):
3396 3396 elif filename.lower().endswith('.vtp'):
3397 3397 reader = vtk.vtkXMLPolyDataReader()
3398 3398 else:
3399   - wx.MessageBox(_("File format not reconized by InVesalius"), _("Import surface error"))
  3399 + wx.MessageBox(_("File format not recognized by InVesalius"), _("Import surface error"))
3400 3400 return
3401 3401 else:
3402 3402 filename = os.path.join(inv_paths.OBJ_DIR, "magstim_fig8_coil.stl")
... ... @@ -3482,18 +3482,34 @@ class ObjectCalibrationDialog(wx.Dialog):
3482 3482 return ball_actor, tactor
3483 3483  
3484 3484 def OnGetObjectFiducials(self, evt):
  3485 + if not self.tracker.IsTrackerInitialized():
  3486 + ShowNavigationTrackerWarning(0, 'choose')
  3487 + return
  3488 +
3485 3489 btn_id = list(const.BTNS_OBJ[evt.GetId()].keys())[0]
3486 3490  
3487   - if self.trk_init and self.tracker_id:
3488   - coord_raw = dco.GetCoordinates(self.trk_init, self.tracker_id, self.obj_ref_id)
3489   - if self.obj_ref_id and btn_id == 4:
3490   - coord = coord_raw[self.obj_ref_id, :]
3491   - else:
3492   - coord = coord_raw[0, :]
3493   - else:
3494   - ShowNavigationTrackerWarning(0, 'choose')
  3491 + coord, coord_raw = self.tracker.GetTrackerCoordinates(
  3492 + # XXX: Always use static reference mode when getting the coordinates. This is what the
  3493 + # code did previously, as well. At some point, it should probably be thought through
  3494 + # if this is actually what we want or if it should be changed somehow.
  3495 + #
  3496 + ref_mode_id=const.STATIC_REF,
  3497 + n_samples=const.CALIBRATION_TRACKER_SAMPLES,
  3498 + )
3495 3499  
3496   - if btn_id == 3:
  3500 + # XXX: The condition below happens when setting the "fixed" coordinate in the object calibration.
  3501 + # The case is not handled by GetTrackerCoordinates function, therefore redo some computation
  3502 + # that is already done once by GetTrackerCoordinates, namely, invert the y-coordinate.
  3503 + #
  3504 + # (What is done here does not seem to be completely consistent with "always use static reference
  3505 + # mode" principle above, but it's hard to come up with a simple change to increase the consistency
  3506 + # and not change the function to the point of potentially breaking it.)
  3507 + #
  3508 + if self.obj_ref_id and btn_id == 4:
  3509 + coord = coord_raw[self.obj_ref_id, :]
  3510 + coord[2] = -coord[2]
  3511 +
  3512 + if btn_id == 3:
3497 3513 coord = np.zeros([6,])
3498 3514  
3499 3515 # Update text controls with tracker coordinates
... ... @@ -3509,7 +3525,7 @@ class ObjectCalibrationDialog(wx.Dialog):
3509 3525 else:
3510 3526 ShowNavigationTrackerWarning(0, 'choose')
3511 3527  
3512   - def OnChoiceRefMode(self, evt):
  3528 + def OnChooseReferenceMode(self, evt):
3513 3529 # When ref mode is changed the tracker coordinates are set to nan
3514 3530 # This is for Polhemus FASTRAK wrapper, where the sensor attached to the object can be the stylus (Static
3515 3531 # reference - Selection 0 - index 0 for coordinates) or can be a 3rd sensor (Dynamic reference - Selection 1 -
... ... @@ -3517,13 +3533,14 @@ class ObjectCalibrationDialog(wx.Dialog):
3517 3533 # I use the index 2 directly here to send to the coregistration module where it is possible to access without
3518 3534 # any conditional statement the correct index of coordinates.
3519 3535  
3520   - if evt.GetSelection():
  3536 + if evt.GetSelection() == 1:
3521 3537 self.obj_ref_id = 2
3522 3538 if self.tracker_id in [const.FASTRAK, const.DEBUGTRACKRANDOM, const.DEBUGTRACKAPPROACH]:
3523 3539 self.choice_sensor.Show(self.obj_ref_id)
3524 3540 else:
3525 3541 self.obj_ref_id = 0
3526 3542 self.choice_sensor.Show(self.obj_ref_id)
  3543 +
3527 3544 for m in range(0, 5):
3528 3545 self.obj_fiducials[m, :] = np.full([1, 3], np.nan)
3529 3546 self.obj_orients[m, :] = np.full([1, 3], np.nan)
... ...
invesalius/gui/task_navigator.py
... ... @@ -582,7 +582,7 @@ class Tracker():
582 582 for i in range(n_samples):
583 583 coord_raw = dco.GetCoordinates(self.trk_init, self.tracker_id, ref_mode_id)
584 584  
585   - if ref_mode_id:
  585 + if ref_mode_id == const.DYNAMIC_REF:
586 586 coord = dco.dynamic_reference_m(coord_raw[0, :], coord_raw[1, :])
587 587 else:
588 588 coord = coord_raw[0, :]
... ... @@ -599,7 +599,7 @@ class Tracker():
599 599 def SetTrackerFiducial(self, ref_mode_id, fiducial_index):
600 600 coord, coord_raw = self.GetTrackerCoordinates(
601 601 ref_mode_id=ref_mode_id,
602   - n_samples=const.FIDUCIAL_REGISTRATION_TRACKER_SAMPLES,
  602 + n_samples=const.CALIBRATION_TRACKER_SAMPLES,
603 603 )
604 604  
605 605 # Update tracker fiducial with tracker coordinates
... ...