Depth estimation
Depth estimation tells how far away each part of an image is. You pass in the pixels and get back a depth map: one number per pixel, smaller for what is nearer to the camera. The numbers are relative, not meters: they order the scene from near to far within one image.
createDepthEstimator runs
DepthART on the
GPU.
Through the transformers.js plugin,
DepthART runs under the Depth Anything V2 model ids,
onnx-community/depth-anything-v2-small and -base. transformers.js has no
DepthART, so a depth-estimation pipeline with one of those ids runs
DepthART, not Depth Anything. The map comes back at 448×448 with smaller
for nearer, the opposite of Depth Anything.
Quick start
Section titled “Quick start”import { function createDepthEstimator(config?: DepthEstimatorModel, opts?: LoadOptions): Promise<DepthEstimator>
createDepthEstimator, function imageBufferFromImageData(img: ImageData): ImageBuffer
imageBufferFromImageData, const models: { readonly embedding: { readonly EMBEDDINGGEMMA_2: { DEFAULT: { modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F16: { dtype: "f16"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F32: { dtype: "f32"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; }; readonly ALL_MINILM_L6_V2: { DEFAULT: { tokenizerPath: string; } & { modelPath: string; }; F16: { tokenizerPath: string; } & { dtype: "f16"; modelPath: string; }; F32: { tokenizerPath: string; } & { modelPath: string; dtype: "f32"; }; }; }; ... 6 more ...; readonly imageClassification: { readonly MOBILENETV4: { readonly DEFAULT: { modelPath: string; }; readonly SMALL: { modelPath: string; }; }; };}
models } from 'runntime/zoo';
// 1. Load the model once. The weights download from the Hugging Face Hub.const const estimator: DepthEstimator
estimator = await function createDepthEstimator(config?: DepthEstimatorModel, opts?: LoadOptions): Promise<DepthEstimator>
createDepthEstimator(const models: { readonly embedding: { readonly EMBEDDINGGEMMA_2: { DEFAULT: { modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F16: { dtype: "f16"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F32: { dtype: "f32"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; }; readonly ALL_MINILM_L6_V2: { DEFAULT: { tokenizerPath: string; } & { modelPath: string; }; F16: { tokenizerPath: string; } & { dtype: "f16"; modelPath: string; }; F32: { tokenizerPath: string; } & { modelPath: string; dtype: "f32"; }; }; }; ... 6 more ...; readonly imageClassification: { readonly MOBILENETV4: { readonly DEFAULT: { modelPath: string; }; readonly SMALL: { modelPath: string; }; }; };}
models.depthEstimation: { readonly DEPTHART: { readonly DEFAULT: { modelPath: string; }; readonly S: { modelPath: string; }; readonly B: { modelPath: string; }; };}
depthEstimation.type DEPTHART: { readonly DEFAULT: { modelPath: string; }; readonly S: { modelPath: string; }; readonly B: { modelPath: string; };}
DEPTHART.type DEFAULT: { modelPath: string;}
DEFAULT);
// 2. Get the pixels of an image, here from a canvas the picture is drawn on.const const ctx: CanvasRenderingContext2D
ctx = const canvas: HTMLCanvasElement
canvas.HTMLCanvasElement.getContext(contextId: "2d", options?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D | null (+5 overloads)
getContext('2d')!;const const image: ImageBuffer
image = function imageBufferFromImageData(img: ImageData): ImageBuffer
imageBufferFromImageData(const ctx: CanvasRenderingContext2D
ctx.CanvasImageData.getImageData(sx: number, sy: number, sw: number, sh: number, settings?: ImageDataSettings): ImageData
getImageData(0, 0, const canvas: HTMLCanvasElement
canvas.HTMLCanvasElement.width: number
width, const canvas: HTMLCanvasElement
canvas.HTMLCanvasElement.height: number
height));
// 3. Estimate the depth.const const depth: DepthMap
depth = await const estimator: DepthEstimator
estimator.DepthEstimator.estimateDepth(image: ImageBuffer): Promise<DepthMap>
estimateDepth(const image: ImageBuffer
image);
// 4. Use it: one value per pixel of the 448×448 map, row by row, smaller = nearer.const { const width: number
width, const height: number
height, const data: Float32Array<ArrayBufferLike>
data } = const depth: DepthMap
depth;const const center: number
center = const data: Float32Array<ArrayBufferLike>
data[(const height: number
height / 2) * const width: number
width + const width: number
width / 2];
// 5. Free the GPU memory when done.const estimator: DepthEstimator
estimator.DepthEstimator.dispose(): void
dispose();The example reads one picture off a canvas. A video or a camera works the
same way: draw each frame on the canvas and call estimateDepth again, the
estimator is loaded once.
The engine must be set up first, see Getting started.
The model runs in half precision, so the device needs shader-f16.
Try it yourself
Section titled “Try it yourself”Your camera, frame by frame through encodeEstimateDepth() on your GPU, as
in GPU in, GPU out: the frame never leaves the GPU and the
map is drawn straight into the canvas, nearest black, farthest white. No
camera? The sample picture goes through the same call.
Results
Section titled “Results”estimateDepth returns one depth map:
interface DepthMap { width: number; // 448 height: number; // 448 data: Float32Array; // width × height values, row by row, smaller = nearer}The map covers the whole image, scaled to the model’s 448×448 input, so
the value for a pixel (x, y) of the image sits at
data[Math.floor(y * height / image.height) * width + Math.floor(x * width / image.width)].
Methods
Section titled “Methods”function createDepthEstimator( model?: DepthEstimatorModel, options?: LoadOptions,): Promise<DepthEstimator>;
interface DepthEstimator { readonly inputSize: number; readonly schemas: { readonly input: DepthInput; readonly output: DepthMapData }; estimateDepth(image: ImageBuffer): Promise<DepthMap>; encodeEstimateDepth(options: EncodeEstimateDepthOptions): void; dispose(): void;}estimateDepth(image)returns one depth map for the image.imageis anImageBufferof any size. Build one withimageBufferFromImageData(imageData)from a canvas, orimageBuffer(bytes, width, height, format?)from rawrgba,rgb,bgra,bgrorgraybytes.encodeEstimateDepth(options)reads an image already on the GPU and writes the map to the GPU, see GPU in, GPU out.inputSizeis the width and height of every returned map, 448.schemasare the TypeGPU layouts of the model input and the depth map, for buffers passed toencodeEstimateDepth.dispose()frees the GPU memory.
GPU in, GPU out
Section titled “GPU in, GPU out”When the image is already on the GPU, a video frame or the output of your
own shader, encodeEstimateDepth skips the CPU: no pixels are read back,
and the map goes straight into a texture or a buffer you own.
import { function createDepthEstimator(config?: DepthEstimatorModel, opts?: LoadOptions): Promise<DepthEstimator>
createDepthEstimator, function initRunntime(root: TgpuRoot): RunntimeExecutor
initRunntime, const models: { readonly embedding: { readonly EMBEDDINGGEMMA_2: { DEFAULT: { modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F16: { dtype: "f16"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F32: { dtype: "f32"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; }; readonly ALL_MINILM_L6_V2: { DEFAULT: { tokenizerPath: string; } & { modelPath: string; }; F16: { tokenizerPath: string; } & { dtype: "f16"; modelPath: string; }; F32: { tokenizerPath: string; } & { modelPath: string; dtype: "f32"; }; }; }; ... 6 more ...; readonly imageClassification: { readonly MOBILENETV4: { readonly DEFAULT: { modelPath: string; }; readonly SMALL: { modelPath: string; }; }; };}
models } from 'runntime/zoo';import const tgpu: { const: { <TDataType extends AnyData>(dataType: TDataType, value: InferGPU<TDataType>): TgpuConst<TDataType>; <TElement extends AnyWgslData>(dataType: (elementCount: number) => WgslArray<TElement>, value: InferGPU<WgslArray<TElement>>): TgpuConst<WgslArray<TElement>>; }; fn: { <Args extends BaseData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, Void>; <Args extends BaseData[] | [], Return extends BaseData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>; <T extends AnyFn>(inner: T): TgpuGenericFn<T>; }; ... 17 more ...; '~unstable': typeof import("/home/runner/work/runntime/runntime/node_modules/.pnpm/typegpu@0.12.5/node_modules/typegpu/tgpuUnstable");}
tgpu from 'typegpu';
// 1. Set up the engine and load the model once.const const root: TgpuRoot
root = await const tgpu: { const: { <TDataType extends AnyData>(dataType: TDataType, value: InferGPU<TDataType>): TgpuConst<TDataType>; <TElement extends AnyWgslData>(dataType: (elementCount: number) => WgslArray<TElement>, value: InferGPU<WgslArray<TElement>>): TgpuConst<WgslArray<TElement>>; }; fn: { <Args extends BaseData[] | []>(argTypes: Args, returnType?: undefined): TgpuFnShell<Args, Void>; <Args extends BaseData[] | [], Return extends BaseData>(argTypes: Args, returnType: Return): TgpuFnShell<Args, Return>; <T extends AnyFn>(inner: T): TgpuGenericFn<T>; }; ... 17 more ...; '~unstable': typeof import("/home/runner/work/runntime/runntime/node_modules/.pnpm/typegpu@0.12.5/node_modules/typegpu/tgpuUnstable");}
tgpu.init: (options?: InitOptions) => Promise<TgpuRoot>
init({ device?: (GPUDeviceDescriptor & { optionalFeatures?: Iterable<GPUFeatureName>;}) | undefined
device: { optionalFeatures?: Iterable<GPUFeatureName> | undefined
optionalFeatures: ['subgroups', 'shader-f16'] } });function initRunntime(root: TgpuRoot): RunntimeExecutor
initRunntime(const root: TgpuRoot
root);const const estimator: DepthEstimator
estimator = await function createDepthEstimator(config?: DepthEstimatorModel, opts?: LoadOptions): Promise<DepthEstimator>
createDepthEstimator(const models: { readonly embedding: { readonly EMBEDDINGGEMMA_2: { DEFAULT: { modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F16: { dtype: "f16"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F32: { dtype: "f32"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; }; readonly ALL_MINILM_L6_V2: { DEFAULT: { tokenizerPath: string; } & { modelPath: string; }; F16: { tokenizerPath: string; } & { dtype: "f16"; modelPath: string; }; F32: { tokenizerPath: string; } & { modelPath: string; dtype: "f32"; }; }; }; ... 6 more ...; readonly imageClassification: { readonly MOBILENETV4: { readonly DEFAULT: { modelPath: string; }; readonly SMALL: { modelPath: string; }; }; };}
models.depthEstimation: { readonly DEPTHART: { readonly DEFAULT: { modelPath: string; }; readonly S: { modelPath: string; }; readonly B: { modelPath: string; }; };}
depthEstimation.type DEPTHART: { readonly DEFAULT: { modelPath: string; }; readonly S: { modelPath: string; }; readonly B: { modelPath: string; };}
DEPTHART.type DEFAULT: { modelPath: string;}
DEFAULT);
// 2. Draw into a canvas on the same device.const const context: GPUCanvasContext
context = const canvas: HTMLCanvasElement
canvas.HTMLCanvasElement.getContext(contextId: "webgpu"): GPUCanvasContext | null (+5 overloads)
getContext('webgpu')!;const context: GPUCanvasContext
context.GPUCanvasContext.configure(configuration: GPUCanvasConfiguration): undefined
configure({ GPUCanvasConfiguration.device: GPUDevice
device: const root: TgpuRoot
root.TgpuRoot.device: GPUDevice
device, GPUCanvasConfiguration.format: GPUTextureFormat
format: var navigator: Navigator
navigator.NavigatorGPU.gpu: GPU
gpu.GPU.getPreferredCanvasFormat(): GPUTextureFormat
getPreferredCanvasFormat() });
// 3. Each frame: video in, depth in the canvas, nearest black, farthest white.function function frame(): void
frame() { const estimator: DepthEstimator
estimator.DepthEstimator.encodeEstimateDepth(options: EncodeEstimateDepthOptions): void
encodeEstimateDepth({ EncodeOptions<GpuImage | GpuTensor<DepthInput>, GpuImageTarget | GpuTensor<DepthMapData>>.source: GpuImage | GpuTensor<DepthInput>
source: const root: TgpuRoot
root.TgpuRoot.device: GPUDevice
device.GPUDevice.importExternalTexture(descriptor: GPUExternalTextureDescriptor): GPUExternalTexture
importExternalTexture({ GPUExternalTextureDescriptor.source: HTMLVideoElement | VideoFrame
source: const video: HTMLVideoElement
video }), EncodeOptions<GpuImage | GpuTensor<DepthInput>, GpuImageTarget | GpuTensor<DepthMapData>>.target: GpuImageTarget | GpuTensor<DepthMapData>
target: const context: GPUCanvasContext
context.GPUCanvasContext.getCurrentTexture(): GPUTexture
getCurrentTexture(), EncodeEstimateDepthOptions.normalize?: "minmax" | "none" | undefined
normalize: 'minmax', }); const video: HTMLVideoElement
video.HTMLVideoElement.requestVideoFrameCallback(callback: VideoFrameRequestCallback): number
requestVideoFrameCallback(function frame(): void
frame);}const video: HTMLVideoElement
video.HTMLVideoElement.requestVideoFrameCallback(callback: VideoFrameRequestCallback): number
requestVideoFrameCallback(function frame(): void
frame);The call records the work and submits it before it returns, so it does not wait for the GPU. Work you submit after it sees the map.
Source - one of:
- a texture: a
GPUTexture, a TypeGPU texture withsampledusage, or aGPUExternalTexturefrom a video. It is fitted like anImageBuffer, with the estimator’sresizeMode, and each value 0-1 counts as a byte 0-255. Formats:rgba8unorm,bgra8unorm,rgb10a2unorm,rgba16float,rgba32float. sRGB formats are rejected: the GPU would turn their values linear, which the model was not trained on. - a buffer holding the model input as is: 3×448×448 f32, normalized RGB,
one plane per channel. A raw
GPUBufferneedsCOPY_SRCusage.
Target - one of:
- a texture: a
GPUTextureor a TypeGPU texture withrenderusage, of any size and any float-renderable format. The map is stretched over it, the same value in every color channel.normalize: 'minmax'maps each map to 0-1, nearest = 0. The default'none'writes the raw values, which an unorm format clamps to 0-1. - a buffer: the 448×448 f32 map, row by row, the same values as
DepthMap.data. A rawGPUBufferneedsCOPY_DSTusage.
With TypeGPU, schemas gives the buffer its type and size:
// [row][column] f32, 448 × 448.const const depth: TgpuBuffer<DepthMapData> & StorageFlag
depth = const root: TgpuRoot
root.TgpuRoot.createBuffer<DepthMapData>(typeSchema: DepthMapData, initial?: ((buffer: TgpuBuffer<NoInfer<DepthMapData>>) => void) | InferInput<NoInfer<DepthMapData>> | undefined): TgpuBuffer<DepthMapData> (+1 overload)
createBuffer(const estimator: DepthEstimator
estimator.DepthEstimator.schemas: { readonly input: DepthInput; readonly output: DepthMapData;}
schemas.output: DepthMapData
output).TgpuBuffer<DepthMapData>.$usage<["storage"]>(usages_0: "storage"): TgpuBuffer<DepthMapData> & StorageFlag
$usage('storage');
const const encoder: TgpuCommandEncoder
encoder = const root: TgpuRoot
root['~unstable'].function createCommandEncoder(descriptor?: GPUCommandEncoderDescriptor): TgpuCommandEncoder
createCommandEncoder();const estimator: DepthEstimator
estimator.DepthEstimator.encodeEstimateDepth(options: EncodeEstimateDepthOptions): void
encodeEstimateDepth({ EncodeOptions<GpuImage | GpuTensor<DepthInput>, GpuImageTarget | GpuTensor<DepthMapData>>.source: GpuImage | GpuTensor<DepthInput>
source: const cameraTexture: GPUTexture
cameraTexture, EncodeOptions<GpuImage | GpuTensor<DepthInput>, GpuImageTarget | GpuTensor<DepthMapData>>.target: GpuImageTarget | GpuTensor<DepthMapData>
target: const depth: TgpuBuffer<DepthMapData> & StorageFlag
depth, EncodeOptions<GpuImage | GpuTensor<DepthInput>, GpuImageTarget | GpuTensor<DepthMapData>>.encoder?: GpuEncoder | undefined
encoder });// ...record your own passes that read `depth` here...const encoder: TgpuCommandEncoder
encoder.TgpuCommandEncoder.submit(): void
submit();encoder - optional. Pass a GPUCommandEncoder or a TypeGPU command
encoder to record the estimate together with your own passes, or several
estimates, into one command buffer. You then finish and submit it
yourself, before dispose().
Every resource must come from the device passed to initRunntime(). A
wrong format, usage or size throws INVALID_ARGUMENT.
Options
Section titled “Options”The first argument is the model config, a plain object with the fields
below. models.depthEstimation.DEPTHART holds ready-made ones: S (13 MB,
the DEFAULT) and B (24 MB, more detail, slower). Pass one as is, copy it
with a field changed, or point at your own safetensors export of a DepthART
relative checkpoint.
interface DepthEstimatorModel { readonly modelPath?: ModelPath; readonly variant?: 'b' | 's'; readonly resizeMode?: 'stretch' | 'letterbox' | 'crop'; // default 'stretch'}
type ModelPath = string | RangeSource; // a URL, or bytes you already haveExamples:
import { function createDepthEstimator(config?: DepthEstimatorModel, opts?: LoadOptions): Promise<DepthEstimator>
createDepthEstimator, const models: { readonly embedding: { readonly EMBEDDINGGEMMA_2: { DEFAULT: { modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F16: { dtype: "f16"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F32: { dtype: "f32"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; }; readonly ALL_MINILM_L6_V2: { DEFAULT: { tokenizerPath: string; } & { modelPath: string; }; F16: { tokenizerPath: string; } & { dtype: "f16"; modelPath: string; }; F32: { tokenizerPath: string; } & { modelPath: string; dtype: "f32"; }; }; }; ... 6 more ...; readonly imageClassification: { readonly MOBILENETV4: { readonly DEFAULT: { modelPath: string; }; readonly SMALL: { modelPath: string; }; }; };}
models } from 'runntime/zoo';
// The base size.await function createDepthEstimator(config?: DepthEstimatorModel, opts?: LoadOptions): Promise<DepthEstimator>
createDepthEstimator(const models: { readonly embedding: { readonly EMBEDDINGGEMMA_2: { DEFAULT: { modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F16: { dtype: "f16"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F32: { dtype: "f32"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; }; readonly ALL_MINILM_L6_V2: { DEFAULT: { tokenizerPath: string; } & { modelPath: string; }; F16: { tokenizerPath: string; } & { dtype: "f16"; modelPath: string; }; F32: { tokenizerPath: string; } & { modelPath: string; dtype: "f32"; }; }; }; ... 6 more ...; readonly imageClassification: { readonly MOBILENETV4: { readonly DEFAULT: { modelPath: string; }; readonly SMALL: { modelPath: string; }; }; };}
models.depthEstimation: { readonly DEPTHART: { readonly DEFAULT: { modelPath: string; }; readonly S: { modelPath: string; }; readonly B: { modelPath: string; }; };}
depthEstimation.type DEPTHART: { readonly DEFAULT: { modelPath: string; }; readonly S: { modelPath: string; }; readonly B: { modelPath: string; };}
DEPTHART.type B: { modelPath: string;}
B);
// Your own copy of the file.await function createDepthEstimator(config?: DepthEstimatorModel, opts?: LoadOptions): Promise<DepthEstimator>
createDepthEstimator({ DepthEstimatorModel.modelPath?: ModelPath | undefined
modelPath: '/models/depthart-s/model.safetensors' });- modelPath - the weights, a
model.safetensorsfile. Default:models.depthEstimation.DEPTHART.DEFAULT.modelPath. - variant - the model size,
bors. Read from the weights by default. - resizeMode - how the image fits the model input.
stretch(default) scales width and height separately, so the map covers the whole image.letterboxpads,cropcuts the centered square.
Loading options
Section titled “Loading options”The second argument controls the download. Every field is optional.
interface LoadOptions { cache?: WeightCache; cacheId?: string; onProgress?: (name: string, doneBytes: number, totalBytes: number) => void; onBytes?: (chunkBytes: number) => void; signal?: AbortSignal;}Example:
import { function createDepthEstimator(config?: DepthEstimatorModel, opts?: LoadOptions): Promise<DepthEstimator>
createDepthEstimator, function createOpfsCache(namespace: string): Promise<WeightCache | undefined>
createOpfsCache, const models: { readonly embedding: { readonly EMBEDDINGGEMMA_2: { DEFAULT: { modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F16: { dtype: "f16"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F32: { dtype: "f32"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; }; readonly ALL_MINILM_L6_V2: { DEFAULT: { tokenizerPath: string; } & { modelPath: string; }; F16: { tokenizerPath: string; } & { dtype: "f16"; modelPath: string; }; F32: { tokenizerPath: string; } & { modelPath: string; dtype: "f32"; }; }; }; ... 6 more ...; readonly imageClassification: { readonly MOBILENETV4: { readonly DEFAULT: { modelPath: string; }; readonly SMALL: { modelPath: string; }; }; };}
models } from 'runntime/zoo';
const const estimator: DepthEstimator
estimator = await function createDepthEstimator(config?: DepthEstimatorModel, opts?: LoadOptions): Promise<DepthEstimator>
createDepthEstimator(const models: { readonly embedding: { readonly EMBEDDINGGEMMA_2: { DEFAULT: { modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F16: { dtype: "f16"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; F32: { dtype: "f32"; modelPath: string; visionPath: string; audioPath: string; tokenizerPath: string; }; }; readonly ALL_MINILM_L6_V2: { DEFAULT: { tokenizerPath: string; } & { modelPath: string; }; F16: { tokenizerPath: string; } & { dtype: "f16"; modelPath: string; }; F32: { tokenizerPath: string; } & { modelPath: string; dtype: "f32"; }; }; }; ... 6 more ...; readonly imageClassification: { readonly MOBILENETV4: { readonly DEFAULT: { modelPath: string; }; readonly SMALL: { modelPath: string; }; }; };}
models.depthEstimation: { readonly DEPTHART: { readonly DEFAULT: { modelPath: string; }; readonly S: { modelPath: string; }; readonly B: { modelPath: string; }; };}
depthEstimation.type DEPTHART: { readonly DEFAULT: { modelPath: string; }; readonly S: { modelPath: string; }; readonly B: { modelPath: string; };}
DEPTHART.type DEFAULT: { modelPath: string;}
DEFAULT, { LoadOptions.cache?: WeightCache | undefined
cache: await function createOpfsCache(namespace: string): Promise<WeightCache | undefined>
createOpfsCache('my-app'), LoadOptions.onProgress?: ((name: string, doneBytes: number, totalBytes: number) => void) | undefined
onProgress: (name: string
name, done: number
done, total: number
total) => var console: Console
console.Console.log(...data: any[]): void
log(`${var Math: Math
Math.Math.round(x: number): number
round((100 * done: number
done) / total: number
total)}%`),});- cache - keeps the downloaded weights in the browser, so the next
visit loads them without the network.
createOpfsCache(name)is the built-in one. - onProgress - called while the weights upload to the GPU, with the tensor name, bytes done and bytes total. Use it for a progress bar.
- signal - an
AbortSignal. Abort it to stop the load between steps. A step already running, like the download or the GPU upload, finishes first.
Supported models
Section titled “Supported models”| Model | Config | Weights | Input | Output |
|---|---|---|---|---|
| DepthART s | models.depthEstimation.DEPTHART.S | f16, 12.6 MB | 448×448 | 448×448 relative depth |
| DepthART b | models.depthEstimation.DEPTHART.B | f16, 23.6 MB | 448×448 | 448×448 relative depth |