@gyeonghokim/fisheye.js 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -51
- package/dist/index.d.ts +96 -113
- package/dist/index.js +232 -194
- package/dist/index.js.map +1 -1
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# fisheye.js
|
|
2
2
|
|
|
3
|
-
DEMO: https://gyeonghokim.github.io/fisheye.js
|
|
3
|
+
DEMO: <https://gyeonghokim.github.io/fisheye.js/>
|
|
4
4
|
|
|
5
|
-
> Modern fisheye
|
|
5
|
+
> Modern fisheye undistortion library for the web using **WebGPU** (general-purpose GPU compute)
|
|
6
6
|
|
|
7
|
-
fisheye.js processes [VideoFrame](https://developer.mozilla.org/en-US/docs/Web/API/VideoFrame)s with **WebGPU compute shaders**—no canvas 2D—and corrects fisheye lens distortion using the **OpenCV fisheye model** (Kannala–Brandt–style polynomial in angle θ with coefficients k1–k4). This is the same model as in [OpenCV
|
|
7
|
+
fisheye.js processes [VideoFrame](https://developer.mozilla.org/en-US/docs/Web/API/VideoFrame)s with **WebGPU compute shaders**—no canvas 2D—and corrects fisheye lens distortion using the **OpenCV fisheye model** (Kannala–Brandt–style polynomial in angle θ with coefficients k1–k4). This is the same model as in [OpenCV's fisheye module](https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html).
|
|
8
8
|
|
|
9
9
|
## Learning Docs
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ See the full educational curriculum in `doc/index.md`.
|
|
|
12
12
|
|
|
13
13
|
## Features
|
|
14
14
|
|
|
15
|
-
- **WebGPU GPGPU**: Compute-shader pipeline via [TypeGPU](https://www.npmjs.com/package/typegpu); input/output as textures and readback to VideoFrame—no canvas element for
|
|
15
|
+
- **WebGPU GPGPU**: Compute-shader pipeline via [TypeGPU](https://www.npmjs.com/package/typegpu); input/output as textures and readback to VideoFrame—no canvas element for undistortion
|
|
16
16
|
- **OpenCV fisheye (Kannala–Brandt) model**: Distortion model `θ_d = θ × (1 + k1·θ² + k2·θ⁴ + k3·θ⁶ + k4·θ⁸)` for accurate calibration
|
|
17
17
|
- **WebCodecs**: Built on the [VideoFrame](https://developer.mozilla.org/en-US/docs/Web/API/VideoFrame) API
|
|
18
18
|
- **ESM**: `import { Fisheye } from "@gyeonghokim/fisheye.js"`
|
|
@@ -37,7 +37,7 @@ if you installed `@webgpu/types`,
|
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
> Why should I install webgpu types?
|
|
40
|
-
> This library does not render your binary, it just
|
|
40
|
+
> This library does not render your binary, it just undistorts the VideoFrame.
|
|
41
41
|
> You should make **your own YUV renderer**, or you can install `@gyeonghokim/yuv-player`.
|
|
42
42
|
|
|
43
43
|
in your code,
|
|
@@ -45,48 +45,45 @@ in your code,
|
|
|
45
45
|
```ts
|
|
46
46
|
import { Fisheye } from "@gyeonghokim/fisheye.js";
|
|
47
47
|
|
|
48
|
-
const
|
|
48
|
+
const fisheye = new Fisheye({
|
|
49
|
+
// OpenCV fisheye distortion coefficients (from calibration)
|
|
49
50
|
k1: 0.5,
|
|
50
51
|
k2: 0.0,
|
|
51
52
|
k3: 0.0,
|
|
52
53
|
k4: 0.0,
|
|
54
|
+
|
|
55
|
+
// Output configuration
|
|
53
56
|
width: 1920,
|
|
54
57
|
height: 1080,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
|
|
59
|
+
// Optional: OpenCV camera matrix parameters
|
|
60
|
+
fx: 1000, // focal length x (pixels)
|
|
61
|
+
fy: 1000, // focal length y (pixels)
|
|
62
|
+
cx: 960, // principal point x (pixels)
|
|
63
|
+
cy: 540, // principal point y (pixels)
|
|
64
|
+
|
|
65
|
+
// Optional: Advanced OpenCV parameters
|
|
66
|
+
balance: 0.0, // 0.0 = all pixels, 1.0 = original FOV
|
|
67
|
+
fovScale: 1.0, // >1.0 = zoom out, <1.0 = zoom in
|
|
68
|
+
|
|
69
|
+
// Optional: Additional features (not part of OpenCV)
|
|
70
|
+
projection: "rectilinear", // "rectilinear" | "equirectangular"
|
|
71
|
+
mount: "ceiling", // "ceiling" | "wall" | "desk"
|
|
59
72
|
});
|
|
60
73
|
|
|
61
|
-
const renderLoop = (timestamp: DOMHighResTimestamp) => {
|
|
62
|
-
//
|
|
63
|
-
const
|
|
64
|
-
yourYUVPlayer.draw(
|
|
74
|
+
const renderLoop = async (timestamp: DOMHighResTimestamp) => {
|
|
75
|
+
// Undistort the fisheye frame
|
|
76
|
+
const undistorted: VideoFrame = await fisheye.undistort(yourVideoFrame);
|
|
77
|
+
yourYUVPlayer.draw(undistorted);
|
|
65
78
|
requestAnimationFrame(renderLoop);
|
|
66
79
|
};
|
|
67
80
|
```
|
|
68
81
|
|
|
69
|
-
##
|
|
82
|
+
## Architecture & Design
|
|
70
83
|
|
|
71
|
-
###
|
|
84
|
+
### Distortion Model: OpenCV Fisheye (Kannala-Brandt)
|
|
72
85
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
**Options:**
|
|
76
|
-
|
|
77
|
-
- `k1` (number, optional): Fisheye distortion coefficient k1. Typical range: -1.0 to 1.0. Default: `0`.
|
|
78
|
-
- `k2` (number, optional): Fisheye distortion coefficient k2. Default: `0`.
|
|
79
|
-
- `k3` (number, optional): Fisheye distortion coefficient k3. Default: `0`.
|
|
80
|
-
- `k4` (number, optional): Fisheye distortion coefficient k4. Default: `0`.
|
|
81
|
-
- `width` (number, optional): Output frame width. Default: `300`
|
|
82
|
-
- `height` (number, optional): Output frame height. Default: `150`
|
|
83
|
-
- `fov` (number, optional): Field of view in degrees. Default: `180`
|
|
84
|
-
- `centerX` (number, optional): X offset of the lens center (normalized, -1.0 to 1.0). Default: `0`
|
|
85
|
-
- `centerY` (number, optional): Y offset of the lens center (normalized, -1.0 to 1.0). Default: `0`
|
|
86
|
-
- `zoom` (number, optional): Zoom factor. Default: `1.0`
|
|
87
|
-
|
|
88
|
-
**Fisheye model (OpenCV fisheye / Kannala–Brandt):**
|
|
89
|
-
We use the same model as OpenCV’s [fisheye module](https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html) (cited there as the “generic camera model” from Kannala & Brandt, 2006). It is a polynomial-in-θ model, not UCM:
|
|
86
|
+
This library uses the **OpenCV fisheye model** (Kannala-Brandt, 2006) for undistortion:
|
|
90
87
|
|
|
91
88
|
```
|
|
92
89
|
theta = atan(r)
|
|
@@ -94,23 +91,123 @@ theta_d = theta * (1 + k1*theta^2 + k2*theta^4 + k3*theta^6 + k4*theta^8)
|
|
|
94
91
|
r_d = tan(theta_d)
|
|
95
92
|
```
|
|
96
93
|
|
|
97
|
-
|
|
94
|
+
This is the same model as [OpenCV's fisheye module](https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html).
|
|
95
|
+
|
|
96
|
+
**Important:** OpenCV's `fisheye.undistortImage()` always outputs **rectilinear (perspective) projection only**. It does not provide panoramic or other projection modes.
|
|
97
|
+
|
|
98
|
+
### Additional Features Beyond OpenCV
|
|
99
|
+
|
|
100
|
+
For **WebGPU efficiency**, we integrate additional transformations in a **single GPU pass** rather than CPU-side post-processing:
|
|
101
|
+
|
|
102
|
+
#### 1. **Projection Mode** (`projection`)
|
|
103
|
+
|
|
104
|
+
- **Purpose**: Controls output coordinate mapping after undistortion
|
|
105
|
+
- **Values**:
|
|
106
|
+
- `"rectilinear"`: Standard perspective projection (same as OpenCV output)
|
|
107
|
+
- `"equirectangular"`: Cylindrical/spherical panoramic projection
|
|
108
|
+
- **Implementation**: Applied in GPU shader after undistortion step
|
|
109
|
+
- **OpenCV equivalent**: Would require separate `cv2.warpPerspective()` or custom remapping after `fisheye.undistortImage()`
|
|
110
|
+
|
|
111
|
+
#### 2. **Mount Orientation** (`mount`)
|
|
112
|
+
|
|
113
|
+
- **Purpose**: Compensates for camera mounting angle
|
|
114
|
+
- **Values**:
|
|
115
|
+
- `"ceiling"`: No rotation (0°)
|
|
116
|
+
- `"wall"`: 90° rotation
|
|
117
|
+
- `"desk"`: 180° or -90° rotation
|
|
118
|
+
- **Implementation**: Applied as rotation transformation in GPU shader
|
|
119
|
+
- **OpenCV equivalent**: Would require `cv2.getRotationMatrix2D()` + `cv2.warpAffine()` after undistortion
|
|
120
|
+
|
|
121
|
+
### Why Unified GPU Pipeline?
|
|
122
|
+
|
|
123
|
+
Traditional OpenCV approach:
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
# Step 1: Undistort (GPU/CPU)
|
|
127
|
+
undistorted = cv2.fisheye.undistortImage(img, K, D, Knew)
|
|
128
|
+
|
|
129
|
+
# Step 2: Projection transform (CPU)
|
|
130
|
+
panorama = cv2.remap(undistorted, custom_map_x, custom_map_y, cv2.INTER_LINEAR)
|
|
131
|
+
|
|
132
|
+
# Step 3: Rotation (CPU)
|
|
133
|
+
rotated = cv2.warpAffine(panorama, rotation_matrix, size)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Our approach (single GPU compute shader):**
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
// All in one GPU pass: undistortion + projection + rotation
|
|
140
|
+
const undistorted = await fisheye.undistort(input);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## API
|
|
144
|
+
|
|
145
|
+
### `new Fisheye(options?: FisheyeOptions)`
|
|
146
|
+
|
|
147
|
+
Creates a new Fisheye undistortion instance.
|
|
148
|
+
|
|
149
|
+
#### OpenCV Fisheye Model Parameters
|
|
150
|
+
|
|
151
|
+
| Parameter | Type | Default | Description |
|
|
152
|
+
| ---------- | --------- | ---------- | -------------------------------------------------------- |
|
|
153
|
+
| `fx` | `number?` | auto | Camera matrix K: focal length in x-axis (pixels) |
|
|
154
|
+
| `fy` | `number?` | auto | Camera matrix K: focal length in y-axis (pixels) |
|
|
155
|
+
| `cx` | `number?` | `width/2` | Camera matrix K: principal point x-coordinate (pixels) |
|
|
156
|
+
| `cy` | `number?` | `height/2` | Camera matrix K: principal point y-coordinate (pixels) |
|
|
157
|
+
| `k1` | `number?` | `0` | Distortion coefficient k1 (Kannala-Brandt) |
|
|
158
|
+
| `k2` | `number?` | `0` | Distortion coefficient k2 (Kannala-Brandt) |
|
|
159
|
+
| `k3` | `number?` | `0` | Distortion coefficient k3 (Kannala-Brandt) |
|
|
160
|
+
| `k4` | `number?` | `0` | Distortion coefficient k4 (Kannala-Brandt) |
|
|
161
|
+
| `width` | `number?` | `300` | Output image width (OpenCV `new_size.width`) |
|
|
162
|
+
| `height` | `number?` | `150` | Output image height (OpenCV `new_size.height`) |
|
|
163
|
+
| `balance` | `number?` | `0.0` | Balance parameter (0.0 = all pixels, 1.0 = original FOV) |
|
|
164
|
+
| `fovScale` | `number?` | `1.0` | FOV scale divisor (>1.0 = zoom out, <1.0 = zoom in) |
|
|
98
165
|
|
|
99
|
-
|
|
166
|
+
**Note:** These parameters exactly match [OpenCV fisheye API](https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html). Use values from `cv2.fisheye.calibrate()` or `cv2.fisheye.estimateNewCameraMatrixForUndistortRectify()`.
|
|
167
|
+
|
|
168
|
+
#### Additional Features (not part of OpenCV)
|
|
169
|
+
|
|
170
|
+
| Parameter | Type | Default | Description |
|
|
171
|
+
| ------------ | -------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------- |
|
|
172
|
+
| `projection` | `"rectilinear"` \| `"equirectangular"` | `"rectilinear"` | Output projection mode. `"rectilinear"` = perspective (same as OpenCV), `"equirectangular"` = panoramic |
|
|
173
|
+
| `mount` | `"ceiling"` \| `"wall"` \| `"desk"` | `"ceiling"` | Camera mount orientation for rotation compensation |
|
|
174
|
+
|
|
175
|
+
### `undistort(frame: VideoFrame): Promise<VideoFrame>`
|
|
176
|
+
|
|
177
|
+
Undistorts a VideoFrame with fisheye distortion.
|
|
100
178
|
|
|
101
179
|
**Parameters:**
|
|
102
180
|
|
|
103
181
|
- `frame`: Input VideoFrame with fisheye distortion
|
|
104
182
|
|
|
105
|
-
**Returns:** Promise that resolves to
|
|
183
|
+
**Returns:** Promise that resolves to an undistorted VideoFrame
|
|
184
|
+
|
|
185
|
+
**Differences from OpenCV:**
|
|
186
|
+
|
|
187
|
+
Unlike OpenCV's `fisheye.undistortImage()` which only outputs rectilinear (perspective) projection, this method performs **all transformations in a single GPU pass** for WebGPU efficiency:
|
|
188
|
+
|
|
189
|
+
1. **Undistortion** (OpenCV fisheye model)
|
|
190
|
+
2. **Projection** (rectilinear or equirectangular, based on `projection` config)
|
|
191
|
+
3. **Mount rotation** (based on `mount` config)
|
|
192
|
+
|
|
193
|
+
OpenCV equivalent would require 3 separate operations:
|
|
194
|
+
```python
|
|
195
|
+
# OpenCV: 3 CPU/GPU roundtrips
|
|
196
|
+
undistorted = cv2.fisheye.undistortImage(img, K, D, Knew)
|
|
197
|
+
panorama = cv2.remap(undistorted, map_x, map_y, cv2.INTER_LINEAR) # if equirectangular
|
|
198
|
+
rotated = cv2.warpAffine(panorama, rotation_matrix, size) # if ceiling/wall/desk
|
|
199
|
+
|
|
200
|
+
# fisheye.js: 1 GPU pass - undistortion + projection + rotation
|
|
201
|
+
undistorted = await fisheye.undistort(img)
|
|
202
|
+
```
|
|
106
203
|
|
|
107
204
|
### `updateConfig(options: Partial<FisheyeOptions>): void`
|
|
108
205
|
|
|
109
|
-
Updates the
|
|
206
|
+
Updates the configuration. You can update any subset of the original options.
|
|
110
207
|
|
|
111
208
|
### `destroy(): void`
|
|
112
209
|
|
|
113
|
-
Cleans up GPU resources. Call this when you're done using the
|
|
210
|
+
Cleans up GPU resources. Call this when you're done using the instance.
|
|
114
211
|
|
|
115
212
|
## Working with YUV Binary Data
|
|
116
213
|
|
|
@@ -119,21 +216,21 @@ If you receive raw YUV binary data from a camera or server, you can use the `cre
|
|
|
119
216
|
```ts
|
|
120
217
|
import { Fisheye, createVideoFrameFromYUV } from "@gyeonghokim/fisheye.js";
|
|
121
218
|
|
|
122
|
-
const
|
|
219
|
+
const fisheye = new Fisheye({ k1: 0.5, width: 1920, height: 1080 });
|
|
123
220
|
|
|
124
221
|
// Example: Receiving NV12 data from a server
|
|
125
222
|
const response = await fetch("/api/camera/frame");
|
|
126
223
|
const yuvBuffer = await response.arrayBuffer();
|
|
127
224
|
|
|
128
225
|
const frame = createVideoFrameFromYUV(new Uint8Array(yuvBuffer), {
|
|
129
|
-
format: "NV12",
|
|
226
|
+
format: "NV12", // YUV format
|
|
130
227
|
width: 1920,
|
|
131
228
|
height: 1080,
|
|
132
|
-
timestamp: performance.now() * 1000,
|
|
229
|
+
timestamp: performance.now() * 1000, // microseconds
|
|
133
230
|
});
|
|
134
231
|
|
|
135
|
-
const
|
|
136
|
-
frame.close();
|
|
232
|
+
const undistorted = await fisheye.undistort(frame);
|
|
233
|
+
frame.close(); // Don't forget to close the original frame
|
|
137
234
|
```
|
|
138
235
|
|
|
139
236
|
### `createVideoFrameFromYUV(data, options)`
|
|
@@ -156,13 +253,13 @@ Creates a VideoFrame from YUV binary data.
|
|
|
156
253
|
|
|
157
254
|
**Supported YUV Formats:**
|
|
158
255
|
|
|
159
|
-
| Format
|
|
160
|
-
|
|
161
|
-
| `I420`
|
|
162
|
-
| `NV12`
|
|
163
|
-
| `I420A` | YUV 4:2:0 planar with alpha
|
|
164
|
-
| `I422`
|
|
165
|
-
| `I444`
|
|
256
|
+
| Format | Description | Data Size |
|
|
257
|
+
| ------- | ----------------------------------------------- | -------------------- |
|
|
258
|
+
| `I420` | YUV 4:2:0 planar (Y, U, V planes) | width × height × 1.5 |
|
|
259
|
+
| `NV12` | YUV 4:2:0 semi-planar (Y plane, interleaved UV) | width × height × 1.5 |
|
|
260
|
+
| `I420A` | YUV 4:2:0 planar with alpha | width × height × 2.5 |
|
|
261
|
+
| `I422` | YUV 4:2:2 planar | width × height × 2 |
|
|
262
|
+
| `I444` | YUV 4:4:4 planar | width × height × 3 |
|
|
166
263
|
|
|
167
264
|
### `calculateYUVDataSize(format, width, height)`
|
|
168
265
|
|
|
@@ -171,7 +268,7 @@ Calculates the expected byte size for YUV data.
|
|
|
171
268
|
```ts
|
|
172
269
|
import { calculateYUVDataSize } from "@gyeonghokim/fisheye.js";
|
|
173
270
|
|
|
174
|
-
const size = calculateYUVDataSize("NV12", 1920, 1080);
|
|
271
|
+
const size = calculateYUVDataSize("NV12", 1920, 1080); // 3110400 bytes
|
|
175
272
|
```
|
|
176
273
|
|
|
177
274
|
## Development
|
package/dist/index.d.ts
CHANGED
|
@@ -121,19 +121,8 @@ export declare interface CreateVideoFrameOptions {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/**
|
|
124
|
-
* Fisheye
|
|
125
|
-
*
|
|
126
|
-
* @example
|
|
127
|
-
* ```ts
|
|
128
|
-
* const dewarper = new Fisheye({
|
|
129
|
-
* width: 1920,
|
|
130
|
-
* height: 1080,
|
|
131
|
-
* fov: 180,
|
|
132
|
-
* projection: "rectilinear",
|
|
133
|
-
* });
|
|
134
|
-
*
|
|
135
|
-
* const dewarpedFrame = await dewarper.dewarp(inputVideoFrame);
|
|
136
|
-
* ```
|
|
124
|
+
* Fisheye undistortion using WebGPU via TypeGPU.
|
|
125
|
+
* Implements OpenCV fisheye model (Kannala-Brandt).
|
|
137
126
|
*/
|
|
138
127
|
export declare class Fisheye {
|
|
139
128
|
private config;
|
|
@@ -142,7 +131,7 @@ export declare class Fisheye {
|
|
|
142
131
|
private inputTexture;
|
|
143
132
|
private outputTexture;
|
|
144
133
|
private bindGroup;
|
|
145
|
-
private
|
|
134
|
+
private pipeline;
|
|
146
135
|
private readbackBuffers;
|
|
147
136
|
private readbackIndex;
|
|
148
137
|
private readbackHasData;
|
|
@@ -153,169 +142,163 @@ export declare class Fisheye {
|
|
|
153
142
|
private outputTextureSize;
|
|
154
143
|
private uniformInputWidth;
|
|
155
144
|
private uniformInputHeight;
|
|
145
|
+
private cachedNewCameraMatrix;
|
|
156
146
|
constructor(options?: FisheyeOptions);
|
|
157
|
-
/**
|
|
158
|
-
* Apply default values to options
|
|
159
|
-
*/
|
|
160
147
|
private applyDefaults;
|
|
161
|
-
/**
|
|
162
|
-
|
|
163
|
-
|
|
148
|
+
/** Undistort a point using Newton's method (OpenCV fisheye inverse). */
|
|
149
|
+
private undistortPointNormalized;
|
|
150
|
+
private undistortPixelToNormalized;
|
|
151
|
+
/** Compute new camera matrix (OpenCV estimateNewCameraMatrixForUndistortRectify). */
|
|
152
|
+
private computeNewCameraMatrix;
|
|
164
153
|
private initialize;
|
|
165
|
-
/**
|
|
166
|
-
* Get uniform data from current configuration
|
|
167
|
-
*/
|
|
168
154
|
private getUniformData;
|
|
169
|
-
/**
|
|
170
|
-
* Update uniform buffer with current configuration
|
|
171
|
-
*/
|
|
172
155
|
private updateUniforms;
|
|
173
156
|
private readbackToVideoFrame;
|
|
174
|
-
/**
|
|
175
|
-
* Create input texture (TypeGPU; per official docs: sampled + render for .write(image/VideoFrame)).
|
|
176
|
-
*/
|
|
177
157
|
private createInputTexture;
|
|
178
|
-
/**
|
|
179
|
-
* Create output storage texture (TypeGPU; type-safe with layout.$)
|
|
180
|
-
*/
|
|
181
158
|
private createOutputTexture;
|
|
182
|
-
/**
|
|
183
|
-
* Calculate bytes per row with proper alignment (256-byte alignment for WebGPU)
|
|
184
|
-
*/
|
|
185
159
|
private calculateBytesPerRow;
|
|
186
|
-
/**
|
|
187
|
-
* Create or recreate readback buffer for GPU to CPU data transfer
|
|
188
|
-
*/
|
|
189
160
|
private createReadbackBuffer;
|
|
190
|
-
/**
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
* @param frame - Input VideoFrame with fisheye distortion
|
|
194
|
-
* @returns Dewarped VideoFrame
|
|
195
|
-
*/
|
|
196
|
-
dewarp(frame: VideoFrame): Promise<VideoFrame>;
|
|
197
|
-
/**
|
|
198
|
-
* Update configuration
|
|
199
|
-
*/
|
|
161
|
+
/** Undistort a VideoFrame. */
|
|
162
|
+
undistort(frame: VideoFrame): Promise<VideoFrame>;
|
|
163
|
+
/** Update configuration. */
|
|
200
164
|
updateConfig(options: Partial<FisheyeOptions>): void;
|
|
201
|
-
/**
|
|
202
|
-
* Clean up GPU resources
|
|
203
|
-
*/
|
|
165
|
+
/** Clean up GPU resources. */
|
|
204
166
|
destroy(): void;
|
|
205
167
|
}
|
|
206
168
|
|
|
207
169
|
/**
|
|
208
|
-
* Internal configuration
|
|
170
|
+
* Internal configuration with all defaults applied.
|
|
171
|
+
*
|
|
172
|
+
* Note: fx, fy, cx, cy are optional because they default to input image dimensions
|
|
173
|
+
* which are not known until undistort() is called.
|
|
209
174
|
*/
|
|
210
|
-
export declare interface FisheyeConfig
|
|
175
|
+
export declare interface FisheyeConfig {
|
|
176
|
+
/** Camera matrix K: fx. Defaults to input width if not specified. */
|
|
177
|
+
fx: number | undefined;
|
|
178
|
+
/** Camera matrix K: fy. Defaults to input width if not specified. */
|
|
179
|
+
fy: number | undefined;
|
|
180
|
+
/** Camera matrix K: cx. Defaults to input width / 2 if not specified. */
|
|
181
|
+
cx: number | undefined;
|
|
182
|
+
/** Camera matrix K: cy. Defaults to input height / 2 if not specified. */
|
|
183
|
+
cy: number | undefined;
|
|
184
|
+
/** Distortion coefficient k1. */
|
|
185
|
+
k1: number;
|
|
186
|
+
/** Distortion coefficient k2. */
|
|
187
|
+
k2: number;
|
|
188
|
+
/** Distortion coefficient k3. */
|
|
189
|
+
k3: number;
|
|
190
|
+
/** Distortion coefficient k4. */
|
|
191
|
+
k4: number;
|
|
192
|
+
/** Output width. */
|
|
193
|
+
width: number;
|
|
194
|
+
/** Output height. */
|
|
195
|
+
height: number;
|
|
196
|
+
/** Balance parameter. */
|
|
197
|
+
balance: number;
|
|
198
|
+
/** FOV scale parameter. */
|
|
199
|
+
fovScale: number;
|
|
200
|
+
/** Output projection mode. */
|
|
201
|
+
projection: FisheyeProjection;
|
|
202
|
+
/** Camera mount position. */
|
|
203
|
+
mount: FisheyeMount;
|
|
211
204
|
}
|
|
212
205
|
|
|
213
206
|
/**
|
|
214
|
-
* Camera mount position.
|
|
215
|
-
* Used for defaults or validation when combined with projection.
|
|
207
|
+
* Camera mount position.
|
|
216
208
|
*/
|
|
217
209
|
export declare type FisheyeMount = "ceiling" | "wall" | "desk";
|
|
218
210
|
|
|
219
211
|
/**
|
|
220
|
-
*
|
|
221
|
-
* as preset names instead of raw options. Example mapping:
|
|
222
|
-
*
|
|
223
|
-
* | User-facing name | mount | projection | fov |
|
|
224
|
-
* |-------------------------|---------|----------------|----------------------|
|
|
225
|
-
* | Panoramic 180 | any | equirectangular| 180 |
|
|
226
|
-
* | 360° Panorama | ceiling | equirectangular| 360 |
|
|
227
|
-
* | Normal / PTZ view | any | rectilinear | e.g. 90 |
|
|
228
|
-
* | Quad (4 panes) | ceiling | rectilinear ×4 | 90 per pane (layout) |
|
|
212
|
+
* Fisheye undistortion configuration.
|
|
229
213
|
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*/
|
|
233
|
-
/**
|
|
234
|
-
* Options for configuring the Fisheye dewarper
|
|
214
|
+
* Based on OpenCV fisheye camera model (Kannala-Brandt).
|
|
215
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
235
216
|
*/
|
|
236
217
|
export declare interface FisheyeOptions {
|
|
237
218
|
/**
|
|
238
|
-
*
|
|
239
|
-
*
|
|
219
|
+
* Camera matrix K: focal length x (pixels).
|
|
220
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
221
|
+
*/
|
|
222
|
+
fx?: number;
|
|
223
|
+
/**
|
|
224
|
+
* Camera matrix K: focal length y (pixels).
|
|
225
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
226
|
+
*/
|
|
227
|
+
fy?: number;
|
|
228
|
+
/**
|
|
229
|
+
* Camera matrix K: principal point x (pixels).
|
|
230
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
231
|
+
*/
|
|
232
|
+
cx?: number;
|
|
233
|
+
/**
|
|
234
|
+
* Camera matrix K: principal point y (pixels).
|
|
235
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
236
|
+
*/
|
|
237
|
+
cy?: number;
|
|
238
|
+
/**
|
|
239
|
+
* Distortion coefficient k1 (Kannala-Brandt).
|
|
240
240
|
* @default 0
|
|
241
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
241
242
|
*/
|
|
242
243
|
k1?: number;
|
|
243
244
|
/**
|
|
244
|
-
*
|
|
245
|
+
* Distortion coefficient k2 (Kannala-Brandt).
|
|
245
246
|
* @default 0
|
|
247
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
246
248
|
*/
|
|
247
249
|
k2?: number;
|
|
248
250
|
/**
|
|
249
|
-
*
|
|
251
|
+
* Distortion coefficient k3 (Kannala-Brandt).
|
|
250
252
|
* @default 0
|
|
253
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
251
254
|
*/
|
|
252
255
|
k3?: number;
|
|
253
256
|
/**
|
|
254
|
-
*
|
|
257
|
+
* Distortion coefficient k4 (Kannala-Brandt).
|
|
255
258
|
* @default 0
|
|
259
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
256
260
|
*/
|
|
257
261
|
k4?: number;
|
|
258
262
|
/**
|
|
259
|
-
* Output image width
|
|
263
|
+
* Output image width (pixels).
|
|
260
264
|
* @default 300
|
|
265
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
261
266
|
*/
|
|
262
267
|
width?: number;
|
|
263
268
|
/**
|
|
264
|
-
* Output image height
|
|
269
|
+
* Output image height (pixels).
|
|
265
270
|
* @default 150
|
|
271
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
266
272
|
*/
|
|
267
273
|
height?: number;
|
|
268
274
|
/**
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
* @
|
|
275
|
+
* Balance between all pixels vs original FOV (0.0-1.0).
|
|
276
|
+
* @default 0.0
|
|
277
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
272
278
|
*/
|
|
273
|
-
|
|
279
|
+
balance?: number;
|
|
274
280
|
/**
|
|
275
|
-
*
|
|
281
|
+
* FOV scale divisor (>1.0 = zoom out, <1.0 = zoom in).
|
|
282
|
+
* @default 1.0
|
|
283
|
+
* @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
|
|
284
|
+
*/
|
|
285
|
+
fovScale?: number;
|
|
286
|
+
/**
|
|
287
|
+
* Output projection mode.
|
|
276
288
|
* @default "rectilinear"
|
|
277
289
|
*/
|
|
278
290
|
projection?: FisheyeProjection;
|
|
279
291
|
/**
|
|
280
|
-
* Camera mount position.
|
|
292
|
+
* Camera mount position.
|
|
281
293
|
* @default "ceiling"
|
|
282
294
|
*/
|
|
283
295
|
mount?: FisheyeMount;
|
|
284
|
-
/**
|
|
285
|
-
* X offset of the lens center (normalized, -1.0 to 1.0).
|
|
286
|
-
* @default 0
|
|
287
|
-
*/
|
|
288
|
-
centerX?: number;
|
|
289
|
-
/**
|
|
290
|
-
* Y offset of the lens center (normalized, -1.0 to 1.0).
|
|
291
|
-
* @default 0
|
|
292
|
-
*/
|
|
293
|
-
centerY?: number;
|
|
294
|
-
/**
|
|
295
|
-
* Zoom factor applied after distortion correction.
|
|
296
|
-
* @default 1.0
|
|
297
|
-
*/
|
|
298
|
-
zoom?: number;
|
|
299
296
|
}
|
|
300
297
|
|
|
301
298
|
/**
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
* - **rectilinear**: Standard perspective (like a normal camera). Straight lines in the
|
|
305
|
-
* scene stay straight; the center is natural, edges are compressed. With wide FOV (e.g.
|
|
306
|
-
* 180°) the edges look very squished. One "window" view.
|
|
307
|
-
*
|
|
308
|
-
* - **equirectangular**: Horizontal axis = azimuth (longitude), vertical = elevation
|
|
309
|
-
* (latitude). The full horizontal span (e.g. 180°) maps linearly to the width, so you
|
|
310
|
-
* get a wide panoramic strip: left = one side, right = the other. Classic panorama look.
|
|
311
|
-
*
|
|
312
|
-
* Commercial equivalents:
|
|
313
|
-
* - "Panoramic 180" / "180° Panorama" → equirectangular with 180° horizontal.
|
|
314
|
-
* - "Panoramic" / "360° Panorama" → equirectangular with 360° horizontal (ceiling mount).
|
|
315
|
-
* - "Normal" / "PTZ view" / single window → rectilinear (often with ~90° FOV per pane).
|
|
316
|
-
* - "Panoramic with 4 panes" / "Quad" → layout of four rectilinear ~90° views, not one projection.
|
|
299
|
+
* Output projection mode.
|
|
317
300
|
*/
|
|
318
|
-
export declare type FisheyeProjection = "rectilinear" | "equirectangular";
|
|
301
|
+
export declare type FisheyeProjection = "rectilinear" | "equirectangular" | "original";
|
|
319
302
|
|
|
320
303
|
/**
|
|
321
304
|
* Supported YUV pixel formats for VideoFrame creation
|