@gyeonghokim/fisheye.js 1.0.2 → 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 CHANGED
@@ -1,14 +1,18 @@
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 dewarping library for the web using **WebGPU** (general-purpose GPU compute)
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 [OpenCVs fisheye module](https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html), not UCM (Unified Camera Model) or a simple radial model.
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
+
9
+ ## Learning Docs
10
+
11
+ See the full educational curriculum in `doc/index.md`.
8
12
 
9
13
  ## Features
10
14
 
11
- - **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 dewarping
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
12
16
  - **OpenCV fisheye (Kannala–Brandt) model**: Distortion model `θ_d = θ × (1 + k1·θ² + k2·θ⁴ + k3·θ⁶ + k4·θ⁸)` for accurate calibration
13
17
  - **WebCodecs**: Built on the [VideoFrame](https://developer.mozilla.org/en-US/docs/Web/API/VideoFrame) API
14
18
  - **ESM**: `import { Fisheye } from "@gyeonghokim/fisheye.js"`
@@ -33,7 +37,7 @@ if you installed `@webgpu/types`,
33
37
  ```
34
38
 
35
39
  > Why should I install webgpu types?
36
- > This library does not render your binary, it just dewarp the VideoFrame.
40
+ > This library does not render your binary, it just undistorts the VideoFrame.
37
41
  > You should make **your own YUV renderer**, or you can install `@gyeonghokim/yuv-player`.
38
42
 
39
43
  in your code,
@@ -41,48 +45,45 @@ in your code,
41
45
  ```ts
42
46
  import { Fisheye } from "@gyeonghokim/fisheye.js";
43
47
 
44
- const dewarper = new Fisheye({
48
+ const fisheye = new Fisheye({
49
+ // OpenCV fisheye distortion coefficients (from calibration)
45
50
  k1: 0.5,
46
51
  k2: 0.0,
47
52
  k3: 0.0,
48
53
  k4: 0.0,
54
+
55
+ // Output configuration
49
56
  width: 1920,
50
57
  height: 1080,
51
- fov: 180, // Field of view in degrees
52
- centerX: 0, // X offset of lens center (-1.0 to 1.0)
53
- centerY: 0, // Y offset of lens center (-1.0 to 1.0)
54
- zoom: 1.0, // Zoom factor
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"
55
72
  });
56
73
 
57
- const renderLoop = (timestamp: DOMHighResTimestamp) => {
58
- // your render logic
59
- const dewarpedVideoFrame: VideoFrame = await dewarper.dewarp(yourVideoFrame);
60
- yourYUVPlayer.draw(dewarpedVideoFrame);
74
+ const renderLoop = async (timestamp: DOMHighResTimestamp) => {
75
+ // Undistort the fisheye frame
76
+ const undistorted: VideoFrame = await fisheye.undistort(yourVideoFrame);
77
+ yourYUVPlayer.draw(undistorted);
61
78
  requestAnimationFrame(renderLoop);
62
79
  };
63
80
  ```
64
81
 
65
- ## API
66
-
67
- ### `new Fisheye(options?: FisheyeOptions)`
68
-
69
- Creates a new Fisheye dewarper instance.
70
-
71
- **Options:**
82
+ ## Architecture & Design
72
83
 
73
- - `k1` (number, optional): Fisheye distortion coefficient k1. Typical range: -1.0 to 1.0. Default: `0`.
74
- - `k2` (number, optional): Fisheye distortion coefficient k2. Default: `0`.
75
- - `k3` (number, optional): Fisheye distortion coefficient k3. Default: `0`.
76
- - `k4` (number, optional): Fisheye distortion coefficient k4. Default: `0`.
77
- - `width` (number, optional): Output frame width. Default: `300`
78
- - `height` (number, optional): Output frame height. Default: `150`
79
- - `fov` (number, optional): Field of view in degrees. Default: `180`
80
- - `centerX` (number, optional): X offset of the lens center (normalized, -1.0 to 1.0). Default: `0`
81
- - `centerY` (number, optional): Y offset of the lens center (normalized, -1.0 to 1.0). Default: `0`
82
- - `zoom` (number, optional): Zoom factor. Default: `1.0`
84
+ ### Distortion Model: OpenCV Fisheye (Kannala-Brandt)
83
85
 
84
- **Fisheye model (OpenCV fisheye / KannalaBrandt):**
85
- 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:
86
87
 
87
88
  ```
88
89
  theta = atan(r)
@@ -90,23 +91,123 @@ theta_d = theta * (1 + k1*theta^2 + k2*theta^4 + k3*theta^6 + k4*theta^8)
90
91
  r_d = tan(theta_d)
91
92
  ```
92
93
 
93
- ### `dewarp(frame: VideoFrame): Promise<VideoFrame>`
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
94
150
 
95
- Dewarps a VideoFrame with fisheye distortion.
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) |
165
+
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.
96
178
 
97
179
  **Parameters:**
98
180
 
99
181
  - `frame`: Input VideoFrame with fisheye distortion
100
182
 
101
- **Returns:** Promise that resolves to a dewarped VideoFrame
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
+ ```
102
203
 
103
204
  ### `updateConfig(options: Partial<FisheyeOptions>): void`
104
205
 
105
- Updates the dewarper configuration. You can update any subset of the original options.
206
+ Updates the configuration. You can update any subset of the original options.
106
207
 
107
208
  ### `destroy(): void`
108
209
 
109
- Cleans up GPU resources. Call this when you're done using the dewarper.
210
+ Cleans up GPU resources. Call this when you're done using the instance.
110
211
 
111
212
  ## Working with YUV Binary Data
112
213
 
@@ -115,21 +216,21 @@ If you receive raw YUV binary data from a camera or server, you can use the `cre
115
216
  ```ts
116
217
  import { Fisheye, createVideoFrameFromYUV } from "@gyeonghokim/fisheye.js";
117
218
 
118
- const dewarper = new Fisheye({ k1: 0.5, width: 1920, height: 1080 });
219
+ const fisheye = new Fisheye({ k1: 0.5, width: 1920, height: 1080 });
119
220
 
120
221
  // Example: Receiving NV12 data from a server
121
222
  const response = await fetch("/api/camera/frame");
122
223
  const yuvBuffer = await response.arrayBuffer();
123
224
 
124
225
  const frame = createVideoFrameFromYUV(new Uint8Array(yuvBuffer), {
125
- format: "NV12", // YUV format
226
+ format: "NV12", // YUV format
126
227
  width: 1920,
127
228
  height: 1080,
128
- timestamp: performance.now() * 1000, // microseconds
229
+ timestamp: performance.now() * 1000, // microseconds
129
230
  });
130
231
 
131
- const dewarpedFrame = await dewarper.dewarp(frame);
132
- frame.close(); // Don't forget to close the original frame
232
+ const undistorted = await fisheye.undistort(frame);
233
+ frame.close(); // Don't forget to close the original frame
133
234
  ```
134
235
 
135
236
  ### `createVideoFrameFromYUV(data, options)`
@@ -152,13 +253,13 @@ Creates a VideoFrame from YUV binary data.
152
253
 
153
254
  **Supported YUV Formats:**
154
255
 
155
- | Format | Description | Data Size |
156
- |--------|-------------|-----------|
157
- | `I420` | YUV 4:2:0 planar (Y, U, V planes) | width × height × 1.5 |
158
- | `NV12` | YUV 4:2:0 semi-planar (Y plane, interleaved UV) | width × height × 1.5 |
159
- | `I420A` | YUV 4:2:0 planar with alpha | width × height × 2.5 |
160
- | `I422` | YUV 4:2:2 planar | width × height × 2 |
161
- | `I444` | YUV 4:4:4 planar | width × height × 3 |
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 |
162
263
 
163
264
  ### `calculateYUVDataSize(format, width, height)`
164
265
 
@@ -167,7 +268,7 @@ Calculates the expected byte size for YUV data.
167
268
  ```ts
168
269
  import { calculateYUVDataSize } from "@gyeonghokim/fisheye.js";
169
270
 
170
- const size = calculateYUVDataSize("NV12", 1920, 1080); // 3110400 bytes
271
+ const size = calculateYUVDataSize("NV12", 1920, 1080); // 3110400 bytes
171
272
  ```
172
273
 
173
274
  ## Development
package/dist/index.d.ts CHANGED
@@ -121,18 +121,8 @@ export declare interface CreateVideoFrameOptions {
121
121
  }
122
122
 
123
123
  /**
124
- * Fisheye dewarper using WebGPU via TypeGPU (Pure GPGPU)
125
- *
126
- * @example
127
- * ```ts
128
- * const dewarper = new Fisheye({
129
- * distortion: 0.5,
130
- * width: 1920,
131
- * height: 1080,
132
- * });
133
- *
134
- * const dewarpedFrame = await dewarper.dewarp(videoFrame);
135
- * ```
124
+ * Fisheye undistortion using WebGPU via TypeGPU.
125
+ * Implements OpenCV fisheye model (Kannala-Brandt).
136
126
  */
137
127
  export declare class Fisheye {
138
128
  private config;
@@ -141,7 +131,7 @@ export declare class Fisheye {
141
131
  private inputTexture;
142
132
  private outputTexture;
143
133
  private bindGroup;
144
- private dewarpPipeline;
134
+ private pipeline;
145
135
  private readbackBuffers;
146
136
  private readbackIndex;
147
137
  private readbackHasData;
@@ -152,115 +142,164 @@ export declare class Fisheye {
152
142
  private outputTextureSize;
153
143
  private uniformInputWidth;
154
144
  private uniformInputHeight;
145
+ private cachedNewCameraMatrix;
155
146
  constructor(options?: FisheyeOptions);
156
- /**
157
- * Apply default values to options
158
- */
159
147
  private applyDefaults;
160
- /**
161
- * Initialize TypeGPU root and resources
162
- */
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;
163
153
  private initialize;
164
- /**
165
- * Get uniform data from current configuration
166
- */
167
154
  private getUniformData;
168
- /**
169
- * Update uniform buffer with current configuration
170
- */
171
155
  private updateUniforms;
172
156
  private readbackToVideoFrame;
173
- /**
174
- * Create input texture (TypeGPU; per official docs: sampled + render for .write(image/VideoFrame)).
175
- */
176
157
  private createInputTexture;
177
- /**
178
- * Create output storage texture (TypeGPU; type-safe with layout.$)
179
- */
180
158
  private createOutputTexture;
181
- /**
182
- * Calculate bytes per row with proper alignment (256-byte alignment for WebGPU)
183
- */
184
159
  private calculateBytesPerRow;
185
- /**
186
- * Create or recreate readback buffer for GPU to CPU data transfer
187
- */
188
160
  private createReadbackBuffer;
189
- /**
190
- * Dewarp a VideoFrame
191
- *
192
- * @param frame - Input VideoFrame with fisheye distortion
193
- * @returns Dewarped VideoFrame
194
- */
195
- dewarp(frame: VideoFrame): Promise<VideoFrame>;
196
- /**
197
- * Update configuration
198
- */
161
+ /** Undistort a VideoFrame. */
162
+ undistort(frame: VideoFrame): Promise<VideoFrame>;
163
+ /** Update configuration. */
199
164
  updateConfig(options: Partial<FisheyeOptions>): void;
200
- /**
201
- * Clean up GPU resources
202
- */
165
+ /** Clean up GPU resources. */
203
166
  destroy(): void;
204
167
  }
205
168
 
206
169
  /**
207
- * Internal configuration after applying defaults
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.
208
174
  */
209
- export declare interface FisheyeConfig extends Required<FisheyeOptions> {
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;
210
204
  }
211
205
 
212
206
  /**
213
- * Options for configuring the Fisheye dewarper
207
+ * Camera mount position.
208
+ */
209
+ export declare type FisheyeMount = "ceiling" | "wall" | "desk";
210
+
211
+ /**
212
+ * Fisheye undistortion configuration.
213
+ *
214
+ * Based on OpenCV fisheye camera model (Kannala-Brandt).
215
+ * @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
214
216
  */
215
217
  export declare interface FisheyeOptions {
216
218
  /**
217
- * Fisheye distortion coefficient k1.
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
+ * @default 0
241
+ * @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
218
242
  */
219
243
  k1?: number;
220
244
  /**
221
- * Fisheye distortion coefficient k2.
245
+ * Distortion coefficient k2 (Kannala-Brandt).
246
+ * @default 0
247
+ * @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
222
248
  */
223
249
  k2?: number;
224
250
  /**
225
- * Fisheye distortion coefficient k3.
251
+ * Distortion coefficient k3 (Kannala-Brandt).
252
+ * @default 0
253
+ * @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
226
254
  */
227
255
  k3?: number;
228
256
  /**
229
- * Fisheye distortion coefficient k4.
257
+ * Distortion coefficient k4 (Kannala-Brandt).
258
+ * @default 0
259
+ * @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
230
260
  */
231
261
  k4?: number;
232
262
  /**
233
- * Canvas width for output
263
+ * Output image width (pixels).
234
264
  * @default 300
265
+ * @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
235
266
  */
236
267
  width?: number;
237
268
  /**
238
- * Canvas height for output
269
+ * Output image height (pixels).
239
270
  * @default 150
271
+ * @see https://docs.opencv.org/4.x/db/d58/group__calib3d__fisheye.html
240
272
  */
241
273
  height?: number;
242
274
  /**
243
- * Field of view in degrees
244
- * @default 180
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
245
278
  */
246
- fov?: number;
279
+ balance?: number;
247
280
  /**
248
- * X offset of the lens center (normalized, -1.0 to 1.0)
249
- * @default 0
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
250
284
  */
251
- centerX?: number;
285
+ fovScale?: number;
252
286
  /**
253
- * Y offset of the lens center (normalized, -1.0 to 1.0)
254
- * @default 0
287
+ * Output projection mode.
288
+ * @default "rectilinear"
255
289
  */
256
- centerY?: number;
290
+ projection?: FisheyeProjection;
257
291
  /**
258
- * Zoom factor
259
- * @default 1.0
292
+ * Camera mount position.
293
+ * @default "ceiling"
260
294
  */
261
- zoom?: number;
295
+ mount?: FisheyeMount;
262
296
  }
263
297
 
298
+ /**
299
+ * Output projection mode.
300
+ */
301
+ export declare type FisheyeProjection = "rectilinear" | "equirectangular" | "original";
302
+
264
303
  /**
265
304
  * Supported YUV pixel formats for VideoFrame creation
266
305
  */