-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_3d_pose.py
More file actions
139 lines (109 loc) · 4.5 KB
/
Copy pathtest_3d_pose.py
File metadata and controls
139 lines (109 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import pyrealsense2 as rs
import numpy as np
import cv2
# -----------------------------
# Global variables
# -----------------------------
clicked_pixel = None
clicked_result = None # (u, v, depth, X, Y, Z)
# -----------------------------
# Mouse callback
# -----------------------------
def mouse_callback(event, x, y, flags, param):
global clicked_pixel
if event == cv2.EVENT_LBUTTONDOWN:
clicked_pixel = (x, y)
# -----------------------------
# Main
# -----------------------------
def main():
global clicked_pixel, clicked_result
pipeline = rs.pipeline()
config = rs.config()
# Stream configuration
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
# Start pipeline
profile = pipeline.start(config)
# Align depth to color frame
align = rs.align(rs.stream.color)
# Get depth scale
depth_sensor = profile.get_device().first_depth_sensor()
depth_scale = depth_sensor.get_depth_scale()
print(f"Depth scale: {depth_scale} m/unit")
# Get color intrinsics
color_stream_profile = profile.get_stream(rs.stream.color).as_video_stream_profile()
intr = color_stream_profile.get_intrinsics()
fx, fy = intr.fx, intr.fy
cx, cy = intr.ppx, intr.ppy
print("Camera intrinsics:")
print(f"fx={fx:.3f}, fy={fy:.3f}, cx={cx:.3f}, cy={cy:.3f}")
cv2.namedWindow("Color")
cv2.setMouseCallback("Color", mouse_callback)
try:
while True:
frames = pipeline.wait_for_frames()
aligned_frames = align.process(frames)
depth_frame = aligned_frames.get_depth_frame()
color_frame = aligned_frames.get_color_frame()
if not depth_frame or not color_frame:
continue
color_image = np.asanyarray(color_frame.get_data())
depth_image = np.asanyarray(depth_frame.get_data())
# Depth colormap for visualization
depth_colormap = cv2.applyColorMap(
cv2.convertScaleAbs(depth_image, alpha=0.03),
cv2.COLORMAP_JET
)
# If pixel clicked, compute 3D coordinate
if clicked_pixel is not None:
u, v = clicked_pixel
# Bounds check
h, w, _ = color_image.shape
if 0 <= u < w and 0 <= v < h:
depth = depth_frame.get_distance(u, v) # meters
if depth > 0:
X = (u - cx) * depth / fx
Y = (v - cy) * depth / fy
Z = depth
clicked_result = (u, v, depth, X, Y, Z)
print("-" * 50)
print(f"Pixel (u, v) = ({u}, {v})")
print(f"Depth Z = {depth:.4f} m")
print(f"3D point = ({X:.4f}, {Y:.4f}, {Z:.4f}) m")
else:
clicked_result = (u, v, 0.0, None, None, None)
print("-" * 50)
print(f"Pixel (u, v) = ({u}, {v})")
print("Invalid depth at this pixel.")
clicked_pixel = None
# Draw clicked result on color image
display_color = color_image.copy()
if clicked_result is not None:
u, v, depth, X, Y, Z = clicked_result
cv2.circle(display_color, (u, v), 5, (0, 255, 0), -1)
if X is not None:
text1 = f"Pixel: ({u},{v})"
text2 = f"Depth: {depth:.3f} m"
text3 = f"3D: ({X:.3f}, {Y:.3f}, {Z:.3f}) m"
else:
text1 = f"Pixel: ({u},{v})"
text2 = "Depth: invalid"
text3 = "3D: unavailable"
cv2.putText(display_color, text1, (10, 25),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 100, 0), 2)
cv2.putText(display_color, text2, (10, 50),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 150, 0), 2)
cv2.putText(display_color, text3, (10, 75),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 200, 0), 2)
# Show images
cv2.imshow("Color", display_color)
cv2.imshow("Depth", depth_colormap)
key = cv2.waitKey(1)
if key == 27: # ESC
break
finally:
pipeline.stop()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()