UNPKG

@thi.ng/pixel-flow

Version:

Naive, lightweight CPU-based dense optical flow implementation

165 lines 5.18 kB
import type { ICopy, Predicate2 } from "@thi.ng/api"; import type { IPixelBuffer } from "@thi.ng/pixel"; /** * Configuration options. See {@link OpticalFlow} for algorithm details. * * @remarks * The resulting flow field will have a resolution of: * * ```text * [ * ceil((imgWidth - 2 * margin) / step), * ceil((imgHeight - 2 * margin) / step) * ] * ``` * * Where `step` is {@link OpticalFlowOpts.step} and `margin` is the sum of * {@link OpticalFlowOpts.windowSize} and {@link OpticalFlowOpts.displace}. */ export interface OpticalFlowOpts { /** * Number of pixels to skip between samples (in both X/Y direction). * * @defaultValue 6 */ step: number; /** * Maximum per-axis displacement distance in pixels used for computing the * frame differences. MUST be a multiple of * {@link OpticalFlowOpts.displaceStep}. * * @remarks * Both this value and `displaceStep` indirectly control the granularity of * flow directions. See {@link OpticalFlow} for algorithm details. * * @defaultValue 9 */ displace: number; /** * Pixel step size to iterate the `[-displace,displace]` interval in each * direction. * * @remarks * Both this value and {@link OpticalFlowOpts.displace} indirectly control * the granularity of flow directions. See {@link OpticalFlow} for algorithm * details. * * @defaultValue 3 */ displaceStep: number; /** * Half the kernel window size, used to compute summed frame difference for * a displace region. MUST be a multiple of * {@link OpticalFlowOpts.windowStep}. * * @remarks * See {@link OpticalFlow} for algorithm details. * * @defaultValue 12 */ windowSize: number; /** * Pixel step size to iterate a single kernel window. Also see * {@link OpticalFlowOpts.windowSize}. * * @defaultValue 3 */ windowStep: number; /** * Amplitude/scale factor of flow vectors. * * @defaultValue 1 */ amp: number; /** * Temporal smoothing linear interpolation factor for flow vectors. * * @defaultValue 0.25 */ smooth: number; /** * Minimum summed difference threshold for a kernel window to be considered * as candidate. Values < 0 mean all deltas are considered. * * @remarks * The summed window difference is computed as: * * ```text * sum(pow(abs(a[i]-b[i])/range,2)) / windowSize * ``` * * Therefore, the thresold also is to be specified in the [0,1] interval. * * @defaultValue 0.001 */ threshold: number; /** * Pixel value range (default: 255). If processing float buffers, this * option likely will have to be set to 1.0. * * @defaultValue 255 */ range: number; /** * Displacement window selection mode (see {@link OpticalFlow} for more details). * * @defaultValue "min" */ mode: "min" | "max"; } /** * Naive dense Optical Flow extraction. See {@link OpticalFlowOpts} for * configuration options and details. * * @remarks * The algorithm requires a previous and current frame. The flow field is * obtained by sampling the current frame at a given * {@link OpticalFlowOpts.step} distance. For each of these sample/grid * positions a kernel window (of `2*windowSize+1` pixels) is being swept/applied * to compute the differences to the previous frame. To compute these * differences, the previous frame is offset multiple times in both X/Y * directions within the `[-displace, +displace)` interval. The kernel computes * the summed difference for each of these displaced window regions and selects * the window with the minimum or maximum change (depending on * {@link OpticalFlowOpts.mode}). The relative (displacement) position of that * selected window is then used as the flow vector for that cell, which will * then be linearly interpolated to apply temporal smoothing of the field * (configurable via {@link OpticalFlowOpts.smooth}) and minimize jittering. */ export declare class OpticalFlow<T extends IPixelBuffer & ICopy<T>> { prev: T; flow: Float64Array; step: number; displace: number; displaceStep: number; windowSize: number; windowStep: number; amp: number; smooth: number; width: number; height: number; margin: number; threshold: number; invRange: number; mode: "min" | "max"; pred: Predicate2<number>; constructor(startFrame: T, opts: Partial<OpticalFlowOpts>); /** * Computes optical flow between given frame and (stored) previous frame, * according to configured options. Returns updated flowfield in a format * compatible with thi.ng/tensors `asTensor()`. * * @remarks * See {@link OpticalFlow} class docs for more details. * * @param curr */ update(curr: T): { type: "f64"; data: Float64Array<ArrayBufferLike>; shape: [number, number, number]; stride: [number, number, number]; dir: number[]; }; } //# sourceMappingURL=index.d.ts.map