0
# Camera
1
2
Camera-related transformations including world-to-image projection pipeline, coordinate system conversions, and camera pose visualization for computer vision applications.
3
4
## Capabilities
5
6
### Projection Pipeline
7
8
Complete camera projection from 3D world coordinates to 2D image coordinates.
9
10
```python { .api }
11
def world2image(P_world, cam2world, sensor_size, image_size, focal_length, image_center=None, kappa=0.0):
12
"""
13
Project 3D world points to 2D image coordinates.
14
15
Parameters:
16
- P_world: array, shape (n_points, 4) - Points in world coordinates
17
- cam2world: array, shape (4, 4) - Camera pose transformation
18
- sensor_size: array, shape (2,) - Physical sensor dimensions [width, height]
19
- image_size: array, shape (2,) - Image dimensions in pixels [width, height]
20
- focal_length: float - Camera focal length
21
- image_center: array, shape (2,), optional - Image center offset
22
- kappa: float, optional - Radial distortion parameter
23
24
Returns:
25
- P_image: array, shape (n_points, 2) - Image coordinates
26
"""
27
28
def cam2sensor(P_cam, focal_length, kappa=0.0):
29
"""
30
Project 3D camera coordinates to 2D sensor plane.
31
32
Parameters:
33
- P_cam: array, shape (n_points, 3 or 4) - Points in camera coordinates
34
- focal_length: float - Camera focal length
35
- kappa: float, optional - Radial distortion parameter
36
37
Returns:
38
- P_sensor: array, shape (n_points, 2) - Points on sensor plane
39
"""
40
41
def sensor2img(P_sensor, sensor_size, image_size, image_center=None):
42
"""
43
Convert sensor coordinates to image pixel coordinates.
44
45
Parameters:
46
- P_sensor: array, shape (n_points, 2) - Points on sensor plane
47
- sensor_size: array, shape (2,) - Physical sensor size [width, height]
48
- image_size: array, shape (2,) - Image size in pixels [width, height]
49
- image_center: array, shape (2,), optional - Image center offset
50
51
Returns:
52
- P_image: array, shape (n_points, 2) - Image pixel coordinates
53
"""
54
```
55
56
### World Grid Generation
57
58
Functions for generating test patterns and calibration grids in world coordinates.
59
60
```python { .api }
61
def make_world_grid(n_lines=11, n_points_per_line=51, xlim=(-0.5, 0.5), ylim=(-0.5, 0.5)):
62
"""
63
Generate grid in world coordinate frame on x-y plane (z=0).
64
65
Parameters:
66
- n_lines: int - Number of grid lines in each direction
67
- n_points_per_line: int - Points per grid line
68
- xlim: tuple - X-axis limits (min, max)
69
- ylim: tuple - Y-axis limits (min, max)
70
71
Returns:
72
- grid: array, shape (2*n_lines*n_points_per_line, 4) - Grid points as homogeneous coordinates
73
"""
74
75
def make_world_line(p1, p2, n_points):
76
"""
77
Generate line between two points in world coordinates.
78
79
Parameters:
80
- p1: array-like, shape (2 or 3,) - Start point
81
- p2: array-like, shape (2 or 3,) - End point
82
- n_points: int - Number of points along line
83
84
Returns:
85
- line: array, shape (n_points, 4) - Line points as homogeneous coordinates
86
"""
87
```
88
89
### Camera Visualization
90
91
3D visualization of camera poses and viewing frustums.
92
93
```python { .api }
94
def plot_camera(ax=None, M=None, cam2world=None, virtual_image_distance=1.0, sensor_size=(1920, 1080), ax_s=1, strict_check=True, **kwargs):
95
"""
96
Plot camera in 3D world coordinates with virtual image plane.
97
98
Parameters:
99
- ax: Axes3D, optional - Matplotlib 3D axis
100
- M: array, shape (3, 4), optional - Camera matrix
101
- cam2world: array, shape (4, 4), optional - Camera pose
102
- virtual_image_distance: float - Distance to virtual image plane
103
- sensor_size: tuple - Sensor dimensions for visualization
104
- ax_s: float - Axis scaling factor
105
- strict_check: bool - Enable strict validation
106
107
Returns:
108
- ax: Axes3D - Matplotlib 3D axis with camera plot
109
"""
110
```
111
112
## Usage Examples
113
114
### Basic Camera Projection
115
116
```python
117
import numpy as np
118
import pytransform3d.camera as pc
119
import pytransform3d.transformations as pt
120
121
# Define camera parameters
122
focal_length = 0.05 # 50mm lens
123
sensor_size = np.array([0.036, 0.024]) # Full frame sensor
124
image_size = np.array([3840, 2560]) # 4K image
125
126
# Camera pose (looking down negative z-axis)
127
cam2world = pt.transform_from(p=[0, 0, 2])
128
129
# Create 3D world points
130
world_points = np.array([
131
[0, 0, 0, 1], # origin
132
[1, 0, 0, 1], # x-axis
133
[0, 1, 0, 1], # y-axis
134
[0, 0, 1, 1], # z-axis
135
])
136
137
# Project to image
138
image_points = pc.world2image(
139
world_points, cam2world, sensor_size, image_size, focal_length
140
)
141
142
print("World points projected to image:")
143
for i, (world_pt, img_pt) in enumerate(zip(world_points, image_points)):
144
print(f" {world_pt[:3]} -> {img_pt}")
145
```
146
147
### Camera Pipeline Steps
148
149
```python
150
import pytransform3d.camera as pc
151
import pytransform3d.transformations as pt
152
153
# Define world points and camera
154
world_points = np.array([[1, 1, 0, 1], [2, 1, 0, 1]])
155
cam2world = pt.transform_from(p=[0, 0, 3])
156
157
# Step 1: Transform to camera coordinates
158
world2cam = pt.invert_transform(cam2world)
159
cam_points = pt.transform(world2cam, world_points)
160
161
# Step 2: Project to sensor plane
162
sensor_points = pc.cam2sensor(cam_points, focal_length=0.05)
163
164
# Step 3: Convert to image pixels
165
sensor_size = np.array([0.036, 0.024])
166
image_size = np.array([1920, 1080])
167
image_points = pc.sensor2img(sensor_points, sensor_size, image_size)
168
169
print(f"Sensor coordinates: {sensor_points}")
170
print(f"Image coordinates: {image_points}")
171
```
172
173
### Camera Visualization
174
175
```python
176
import matplotlib.pyplot as plt
177
import pytransform3d.camera as pc
178
import pytransform3d.transformations as pt
179
from pytransform3d.plot_utils import make_3d_axis
180
181
# Create cameras at different poses
182
cameras = [
183
pt.transform_from(p=[2, 0, 1]),
184
pt.transform_from(p=[0, 2, 1]),
185
pt.transform_from(p=[-2, 0, 1]),
186
]
187
188
# Plot scene
189
ax = make_3d_axis(ax_s=3)
190
191
# Plot coordinate origin
192
ax.scatter([0], [0], [0], c='red', s=100, label='Origin')
193
194
# Plot cameras
195
for i, cam_pose in enumerate(cameras):
196
pc.plot_camera(ax=ax, cam2world=cam_pose, virtual_image_distance=0.5)
197
198
ax.set_xlabel('X')
199
ax.set_ylabel('Y')
200
ax.set_zlabel('Z')
201
ax.legend()
202
plt.show()
203
```
204
205
### Calibration Grid
206
207
```python
208
import pytransform3d.camera as pc
209
import matplotlib.pyplot as plt
210
211
# Generate calibration grid
212
grid = pc.make_world_grid(n_lines=10, n_points_per_line=10,
213
xlim=(-0.5, 0.5), ylim=(-0.5, 0.5))
214
215
# Plot grid in 3D
216
fig = plt.figure()
217
ax = fig.add_subplot(111, projection='3d')
218
ax.scatter(grid[:, 0], grid[:, 1], grid[:, 2], s=1)
219
ax.set_xlabel('X')
220
ax.set_ylabel('Y')
221
ax.set_zlabel('Z')
222
plt.show()
223
224
# Project grid to image
225
cam2world = pt.transform_from(p=[0, 0, 1])
226
image_points = pc.world2image(grid, cam2world,
227
np.array([0.036, 0.024]),
228
np.array([1920, 1080]),
229
0.05)
230
231
# Plot projected grid
232
plt.figure()
233
plt.scatter(image_points[:, 0], image_points[:, 1], s=1)
234
plt.xlabel('Image X (pixels)')
235
plt.ylabel('Image Y (pixels)')
236
plt.title('Projected Calibration Grid')
237
plt.show()
238
```