106 parser = argparse.ArgumentParser(description=
'Pose estimation with XFeat')
108 parser.add_argument(
'--database', type=str, required=
True, help=
'Path where to save the keypoints and their descriptors. If it already exists, then it will be used to load keypoints.')
109 parser.add_argument(
'--object', type=str, required=
True, help=
'Path to the .obj file of the object for which to estimate the pose')
110 parser.add_argument(
'--rbt-config', type=str, required=
True, help=
'Path to the Render Based Tracker configuration. It is used to continuously estimate the pose in the learning step')
111 parser.add_argument(
'--init-file', type=str, help=
'An initialization file, required to init tracker when XFeat points have not yet been learned.')
113 parser.add_argument(
'--width', type=int, default=640, help=
'Width of the input images')
114 parser.add_argument(
'--height', type=int, default=480, help=
'Height of the input images')
115 parser.add_argument(
'--fps', type=int, default=60, help=
'Camera framerate')
117 args = parser.parse_args()
119 db_path = Path(args.database).absolute()
120 is_learning =
not db_path.exists()
122 object_path = Path(args.object).absolute()
123 rbt_path = Path(args.rbt_config).absolute()
125 assert object_path.exists()
126 assert rbt_path.exists()
129 pose_estimator.optim_params.gain = 0.5
130 pose_estimator.optim_params.minImprovementFactor = 0.001
134 exts = PythonRBExtensions()
137 print(
'Database was not found, going into learning mode!')
139 print(
'Setting up tracker..')
140 tracker = RBTracker()
142 tracker.loadConfigurationFile(str(rbt_path))
144 exts.parse_python_extensions(tracker, rbt_path)
145 tracker.setModelPath(str(object_path))
146 tracker.setCameraParameters(frame_source.intrinsics(), frame_source.h, frame_source.w)
147 tracker.startTracking()
149 learn_loop(args, tracker, frame_source, pose_estimator)
156 display_frames.display(frame.I, frame.IRGB, frame.I_depth)
157 Display.displayText(display_frames.I_disp, 10, 10,
'Click to initialize by click', Color.red)
158 display_frames.flush()
160 clicked = Display.getClick(display_frames.I_disp, blocking=
False)
163 tracker.initClick(display_frames.I_disp, str(init_path),
True)
166def learn_loop(args, tracker: RBTracker, frame_source: RealSenseSource, pose_estimator: XFeatViewPointPoseEstimator):
167 frames = frame_source.frames()
168 display_frames =
DisplayFrames(frame_source.h, frame_source.w)
169 print(
'Initializing tracker before recording keypoints...')
171 if args.init_file
is None:
172 raise RuntimeError(
'Init file is required to initialize the Render Base tracker before learning keypoints.')
173 init_path = Path(args.init_file).absolute()
177 cMo = HomogeneousMatrix()
179 print(
'Tracker was initialized with pose:\n', cMo)
182 tracking_result = tracker.track(frame.I, frame.IRGB, frame.I_depth)
186 display_frames.display(frame.I, frame.IRGB, frame.I_depth)
187 tracker.display(display_frames.I_disp, display_frames.rgb_disp, display_frames.depth_disp)
189 Display.displayText(display_frames.I_disp, 10, 10,
'Left click to record a viewpoint', Color.red)
190 Display.displayText(display_frames.I_disp, 10 + line_height, 10,
'Right click to stop', Color.red)
191 Display.displayText(display_frames.I_disp, 10 + line_height * 2, 10,
'Press R to reinitialize', Color.red)
193 button = MouseButton.MouseButtonType.none
194 clicked = Display.getClick(display_frames.I_disp, button, blocking=
False)
195 key_pressed, key = Display.getKeyboardEventWithKey(display_frames.I_disp, blocking=
False)
199 if button == MouseButton.button1:
200 pose_estimator.record(tracker.getMostRecentFrame(), cMo)
201 print(
'Recorded new viewpoint')
203 elif button == MouseButton.button3:
204 pose_estimator.save()
205 print(
'Finished recording, exiting...')
207 display_frames.flush()
210 if key.lower() ==
'r':
216def estimation_loop(object_path: Path, frame_source: RealSenseSource, pose_estimator: XFeatViewPointPoseEstimator):
217 frames = frame_source.frames()
218 display_frames =
DisplayFrames(frame_source.h, frame_source.w)
220 last_estimated_cMo = HomogeneousMatrix()
221 h, w = frame_source.h, frame_source.w
222 canny_or, canny_valid = ImageFloat(h, w), ImageGray(h, w)
225 geometry_renderer = Panda3DGeometryRenderer(Panda3DGeometryRenderer.RenderType.OBJECT_NORMALS,
False)
226 canny_renderer = Panda3DDepthCannyFilter(
'canny', geometry_renderer,
True, 0.01)
227 renderer = Panda3DRendererSet()
229 renderer.addSubRenderer(geometry_renderer)
230 renderer.addSubRenderer(canny_renderer)
232 render_params = Panda3DRenderParameters(frame_source.intrinsics(), frame_source.h, frame_source.w, 0.001, 0.25)
233 renderer.setRenderParameters(render_params)
234 renderer.initFramework()
235 renderer.addObjectToScene(
'object', str(object_path))
237 display_frames.display(frame.I, frame.IRGB, frame.I_depth)
239 if point_indices
is not None:
240 for vs, us
in zip(*point_indices):
241 Display.displayPoint(display_frames.I_disp, vs, us, Color.green, thickness=2)
242 Display.displayText(display_frames.I_disp, 10, 10,
'Left click to perform pose estimation', Color.red)
243 Display.displayText(display_frames.I_disp, 10 + line_height, 10,
'Right click to stop', Color.red)
244 button = MouseButton.MouseButtonType.none
245 clicked = Display.getClick(display_frames.I_disp, button, blocking=
False)
248 if button == MouseButton.button1:
249 pose_ok, cMo = pose_estimator.estimate_pose(frame.IRGB, frame.I_depth, frame_source.intrinsics())
251 print(
'Pose estimation was detected as successful!')
253 last_estimated_cMo = cMo
254 renderer.setCameraPose(cMo.inverse())
255 nearV, farV = geometry_renderer.computeNearAndFarPlanesFromNode(
'object',
True)
256 params = Panda3DRenderParameters(frame_source.intrinsics(), frame_source.h, frame_source.w, nearV, farV)
257 renderer.setRenderParameters(params)
258 renderer.renderFrame()
259 canny_renderer.getRender(canny_or, canny_valid)
260 point_indices = np.nonzero(canny_valid.numpy())
262 elif button == MouseButton.button3:
263 print(
'Finished pose estimation test, exiting...')
266 for frame_display
in [display_frames.I_disp, display_frames.rgb_disp, display_frames.depth_disp]:
267 Display.displayFrame(frame_display, last_estimated_cMo, frame_source.intrinsics(), 0.05)
269 display_frames.flush()
271 from visp.ar
import Panda3DFrameworkManager
272 Panda3DFrameworkManager.getInstance().exit()