Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
realsense-mbt.py
35
36import argparse
37from dataclasses import dataclass
38from pathlib import Path
39from typing import List, Optional, Tuple
40import numpy as np
41import time
42import faulthandler
43faulthandler.enable()
44
45from visp.core import CameraParameters, HomogeneousMatrix
46from visp.core import Color, Display, ImageConvert
47from visp.core import ImageGray, ImageUInt16, ImageRGBa
48from visp.io import ImageIo
49from visp.mbt import MbGenericTracker
50from visp.python.display_utils import get_display
51import pyrealsense2 as rs
52
53try:
54 import cv2
55except:
56 print('Could not import opencv-python! make sure that it is installed as it is required')
57 import sys
58 sys.exit(1)
59
60import matplotlib.pyplot as plt
61
62
64 def __init__(self, data_root: Path, object_name: str):
65 model_path = data_root / 'model' / object_name
66 assert model_path.exists()
67 self.config_color = model_path / f'{object_name}.xml'
68 self.config_depth = model_path / f'{object_name}_depth.xml'
69 self.cad_file = model_path / f'{object_name}.cao'
70 self.init_file = model_path / f'{object_name}.init'
71
72
74 def __init__(self, data_root: Path):
75 data_path = data_root / 'data'
76 assert data_path.exists()
77 self.extrinsic_file = str(data_path / 'depth_M_color.txt')
78
79
80@dataclass
82 I: ImageGray
83 I_depth: Optional[ImageUInt16]
84 point_cloud: Optional[np.ndarray]
85
86
87
88
89def read_data(cam_depth: CameraParameters | None, I: ImageGray, pipe: rs.pipeline):
90 use_depth = cam_depth is not None
91 iteration = 1
92 point_cloud_computer = rs.pointcloud()
93 while True:
94 frames = pipe.wait_for_frames()
95 I_np = np.asanyarray(frames.get_color_frame().as_frame().get_data())
96 I_np = np.concatenate((I_np, np.ones_like(I_np[..., 0:1], dtype=np.uint8)), axis=-1)
97 I_rgba = ImageRGBa(I_np)
98 ImageConvert.convert(I_rgba, I, 0)
99 I_depth_raw = None
100 point_cloud = None
101 if use_depth:
102 I_depth_raw = np.asanyarray(frames.get_depth_frame().as_frame().get_data())
103 point_cloud = np.asanyarray(point_cloud_computer.calculate(frames.get_depth_frame()).get_vertices()).view((np.float32, 3))
104 iteration += 1
105 yield FrameData(I, ImageUInt16(I_depth_raw), point_cloud)
106
107
108
109def cam_from_rs_profile(profile) -> Tuple[CameraParameters, int, int]:
110 intr = profile.as_video_stream_profile().get_intrinsics() # Downcast to video_stream_profile and fetch intrinsics
111 return CameraParameters(intr.fx, intr.fy, intr.ppx, intr.ppy), intr.height, intr.width
112
113if __name__ == '__main__':
114 parser = argparse.ArgumentParser()
115 parser.add_argument('--data-root', type=str, required=True,
116 help='Path to the folder containing all the data for the MBT example.')
117 parser.add_argument('--object-name', type=str, required=True,
118 help='Name of the object to track.')
119 parser.add_argument('--disable-klt', action='store_true', help='Disable KLT features for tracking.')
120 parser.add_argument('--disable-depth', action='store_true', help='Do not use depth to perform tracking.')
121 parser.add_argument('--step-by-step', action='store_true', help='Perform tracking frame by frame. Go to the next frame by clicking.')
122
123
124 args = parser.parse_args()
125 data_root = Path(args.data_root)
126
127
128 # Initialize realsense2
129 pipe = rs.pipeline()
130 config = rs.config()
131 config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 60)
132 config.enable_stream(rs.stream.color, 640, 480, rs.format.rgb8, 60)
133
134 cfg = pipe.start(config)
135
136 assert data_root.exists() and data_root.is_dir()
137
138 mbt_model = MBTModelData(data_root, args.object_name)
139 exp_config = MBTConfig(data_root)
140
141 cam_color, color_height, color_width = cam_from_rs_profile(cfg.get_stream(rs.stream.color))
142 cam_depth, depth_height, depth_width = cam_from_rs_profile(cfg.get_stream(rs.stream.depth))
143
144
145 rgb_tracker: int = MbGenericTracker.EDGE_TRACKER | (MbGenericTracker.KLT_TRACKER if not args.disable_klt else 0)
146 tracker_types: List[int] = [rgb_tracker]
147 if not args.disable_depth:
148 depth_tracker = MbGenericTracker.DEPTH_DENSE_TRACKER
149 tracker_types.append(depth_tracker)
150
151 tracker = MbGenericTracker(tracker_types)
152
153 if args.disable_depth:
154 tracker.loadConfigFile(str(mbt_model.config_color))
155 else:
156 tracker.loadConfigFile(str(mbt_model.config_color), str(mbt_model.config_depth))
157 tracker.loadModel(str(mbt_model.cad_file))
158
159 # Camera intrinsics
160
161 tracker.setCameraParameters(*((cam_color,) if args.disable_depth else (cam_color, cam_depth)))
162 tracker.setDisplayFeatures(True)
163
164 print('Color intrinsics:', cam_color)
165 print('Depth intrinsics:', cam_depth)
166 I = ImageGray()
167 data_generator = read_data(cam_depth, I, pipe)
168 frame_data = next(data_generator) # Get first frame for init
169
170 depth_M_color = HomogeneousMatrix()
171 if not args.disable_depth:
172 depth_M_color.load(exp_config.extrinsic_file)
173 tracker.setCameraTransformationMatrix('Camera2', depth_M_color)
174
175 # Initialize displays
176 dI = get_display()
177 dI.init(I, 0, 0, 'Color image')
178
179 I_depth = None if args.disable_depth else ImageGray()
180 dDepth = get_display()
181 if not args.disable_depth:
182 ImageConvert.createDepthHistogram(frame_data.I_depth, I_depth)
183 dDepth.init(I_depth, I.getWidth(), 0, 'Depth')
184
185 for frame in data_generator:
186 Display.display(I)
187 Display.displayText(I, 0, 0, 'Click to initialize tracking', Color.red)
188 Display.flush(I)
189 event = Display.getClick(I, blocking=False)
190 if event:
191 break
192
193 tracker.initClick(I, str(mbt_model.init_file))
194 start_time = time.time()
195 for frame_data in data_generator:
196 if I_depth is not None:
197 ImageConvert.createDepthHistogram(frame_data.I_depth, I_depth)
198
199 Display.display(I)
200 if not args.disable_depth:
201 Display.display(I_depth)
202
203 if args.disable_depth:
204 tracker.track(I=I)
205 else:
206 pc = frame_data.point_cloud
207 image_dict = {
208 'Camera1': I
209 }
210 t = time.time()
211 tracker.track(image_dict, {'Camera2': pc.reshape(depth_height, depth_width, 3)})
212 cMo = HomogeneousMatrix()
213 tracker.getPose(cMo)
214
215 Display.displayFrame(I, cMo, cam_color, 0.05, Color.none, 2)
216 tracker.display(I, cMo, cam_color, Color.red, 2)
217 Display.flush(I)
218 if not args.disable_depth:
219 Display.flush(I_depth)
220
221 if args.step_by_step:
222 Display.getKeyboardEvent(I, blocking=True)
223 else:
224 event = Display.getClick(I, blocking=False)
225 if event:
226 break
227 end_time = time.time()
228 print(f'total time = {end_time - start_time}s')
__init__(self, Path data_root)
__init__(self, Path data_root, str object_name)
Tuple[CameraParameters, int, int] cam_from_rs_profile(profile)
read_data(CameraParameters|None cam_depth, ImageGray I, rs.pipeline pipe)