Commit fb3be70a185a1670ede4105f4e5dad4e954b9de0
1 parent
f6aaa89a
Exists in
master
ENH: Dialog to show ICP error
-ICP error: Mean distance between points and the closest surface
Showing
2 changed files
with
57 additions
and
23 deletions
Show diff stats
invesalius/gui/dialogs.py
... | ... | @@ -908,6 +908,18 @@ def ICPcorregistration(fre): |
908 | 908 | dlg.Destroy() |
909 | 909 | return flag |
910 | 910 | |
911 | +def ReportICPerror(prev_error, final_error): | |
912 | + msg = _("The average error after ICP is: ") + str(round(final_error, 2)) + ' mm' + '\n\n' + \ | |
913 | + _("The previously average error was: ") + str(round(prev_error, 2)) + ' mm' | |
914 | + if sys.platform == 'darwin': | |
915 | + dlg = wx.MessageDialog(None, "", msg, | |
916 | + wx.OK) | |
917 | + else: | |
918 | + dlg = wx.MessageDialog(None, msg, "InVesalius 3", | |
919 | + wx.OK) | |
920 | + dlg.ShowModal() | |
921 | + dlg.Destroy() | |
922 | + | |
911 | 923 | def ShowEnterMarkerID(default): |
912 | 924 | msg = _("Edit marker ID") |
913 | 925 | if sys.platform == 'darwin': |
... | ... | @@ -3719,6 +3731,45 @@ class ICPCorregistrationDialog(wx.Dialog): |
3719 | 3731 | m[i, j] = matrix.GetElement(i, j) |
3720 | 3732 | return m |
3721 | 3733 | |
3734 | + def SetCameraVolume(self, position): | |
3735 | + cam_focus = np.array([position[0], -position[1], position[2]]) | |
3736 | + cam = self.ren.GetActiveCamera() | |
3737 | + | |
3738 | + if self.initial_focus is None: | |
3739 | + self.initial_focus = np.array(cam.GetFocalPoint()) | |
3740 | + | |
3741 | + cam_pos0 = np.array(cam.GetPosition()) | |
3742 | + cam_focus0 = np.array(cam.GetFocalPoint()) | |
3743 | + v0 = cam_pos0 - cam_focus0 | |
3744 | + v0n = np.sqrt(inner1d(v0, v0)) | |
3745 | + | |
3746 | + v1 = (cam_focus - self.initial_focus) | |
3747 | + | |
3748 | + v1n = np.sqrt(inner1d(v1, v1)) | |
3749 | + if not v1n: | |
3750 | + v1n = 1.0 | |
3751 | + cam_pos = (v1/v1n)*v0n + cam_focus | |
3752 | + | |
3753 | + cam.SetFocalPoint(cam_focus) | |
3754 | + cam.SetPosition(cam_pos) | |
3755 | + self.Refresh() | |
3756 | + | |
3757 | + def ErrorEstimation(self, surface, Points): | |
3758 | + cell_locator = vtk.vtkCellLocator() | |
3759 | + cell_locator.SetDataSet(surface) | |
3760 | + cell_locator.BuildLocator() | |
3761 | + | |
3762 | + cellId = vtk.mutable(0) | |
3763 | + c = [0.0, 0.0, 0.0] | |
3764 | + subId = vtk.mutable(0) | |
3765 | + d = vtk.mutable(0.0) | |
3766 | + error = [] | |
3767 | + for i in range(len(Points)): | |
3768 | + cell_locator.FindClosestPoint(Points[i], c, cellId, subId, d) | |
3769 | + error.append(np.sqrt(float(d))) | |
3770 | + | |
3771 | + return np.mean(error) | |
3772 | + | |
3722 | 3773 | def OnChoiceICPMethod(self, evt): |
3723 | 3774 | self.icp_mode = evt.GetSelection() |
3724 | 3775 | |
... | ... | @@ -3787,29 +3838,10 @@ class ICPCorregistrationDialog(wx.Dialog): |
3787 | 3838 | actor.GetProperty().SetColor((0,1,0)) |
3788 | 3839 | |
3789 | 3840 | self.ren.AddActor(actor) |
3790 | - self.Refresh() | |
3791 | 3841 | |
3792 | - def SetCameraVolume(self, position): | |
3793 | - cam_focus = np.array([position[0], -position[1], position[2]]) | |
3794 | - cam = self.ren.GetActiveCamera() | |
3842 | + self.prev_error = self.ErrorEstimation(self.surface, sourcePoints) | |
3843 | + self.final_error = self.ErrorEstimation(self.surface, self.transformed_points) | |
3795 | 3844 | |
3796 | - if self.initial_focus is None: | |
3797 | - self.initial_focus = np.array(cam.GetFocalPoint()) | |
3798 | - | |
3799 | - cam_pos0 = np.array(cam.GetPosition()) | |
3800 | - cam_focus0 = np.array(cam.GetFocalPoint()) | |
3801 | - v0 = cam_pos0 - cam_focus0 | |
3802 | - v0n = np.sqrt(inner1d(v0, v0)) | |
3803 | - | |
3804 | - v1 = (cam_focus - self.initial_focus) | |
3805 | - | |
3806 | - v1n = np.sqrt(inner1d(v1, v1)) | |
3807 | - if not v1n: | |
3808 | - v1n = 1.0 | |
3809 | - cam_pos = (v1/v1n)*v0n + cam_focus | |
3810 | - | |
3811 | - cam.SetFocalPoint(cam_focus) | |
3812 | - cam.SetPosition(cam_pos) | |
3813 | 3845 | self.Refresh() |
3814 | 3846 | |
3815 | 3847 | def OnContinuousAcquisition(self, evt=None, btn=None): |
... | ... | @@ -3832,7 +3864,7 @@ class ICPCorregistrationDialog(wx.Dialog): |
3832 | 3864 | self.LoadActor() |
3833 | 3865 | |
3834 | 3866 | def GetValue(self): |
3835 | - return self.m_icp, self.point_coord, self.transformed_points | |
3867 | + return self.m_icp, self.point_coord, self.transformed_points, self.prev_error, self.final_error | |
3836 | 3868 | |
3837 | 3869 | class SurfaceProgressWindow(object): |
3838 | 3870 | def __init__(self): | ... | ... |
invesalius/gui/task_navigator.py
... | ... | @@ -702,7 +702,9 @@ class NeuronavigationPanel(wx.Panel): |
702 | 702 | def OnICP(self): |
703 | 703 | dialog = dlg.ICPCorregistrationDialog(nav_prop=(self.tracker_id, self.trk_init, self.ref_mode_id)) |
704 | 704 | if dialog.ShowModal() == wx.ID_OK: |
705 | - self.m_icp, point_coord, transformed_points = dialog.GetValue() | |
705 | + self.m_icp, point_coord, transformed_points, prev_error, final_error = dialog.GetValue() | |
706 | + dlg.ReportICPerror(prev_error, final_error) | |
707 | + #TODO: checkbox in the dialog to transfer the icp points to 3D viewer | |
706 | 708 | #create markers |
707 | 709 | # for i in range(len(point_coord)): |
708 | 710 | # img_coord = point_coord[i][0],-point_coord[i][1],point_coord[i][2], 0, 0, 0 | ... | ... |