circle_bundles.optical_flow

Optical flow utilities: preprocessing, contrast/feature extraction, patch sampling, frame I/O helpers, and visualization helpers.

circle_bundles.optical_flow.get_contrast_norms(data, *, patch_type='opt_flow')[source]

Vectorized contrast norms.

Parameters:
  • data (array of shape (N, n^2) for intensity patches,) – or (N, 2*n^2) for optical flow (u then v).

  • patch_type ({'img','opt_flow','flow'}) – ‘flow’ is accepted as an alias for ‘opt_flow’.

Returns:

norms

Return type:

(N,) array, sqrt( x^T D x ) (and sum across u,v for flow)

circle_bundles.optical_flow.get_dct_basis(N, *, normalize=True, opt_flow=False, top_two=False)[source]

Generate a 2D DCT-II basis for N×N patches.

Returns:

  • basis ((M, N^2) if opt_flow=False) – (2*M, 2*N^2) if opt_flow=True (stack horizontal then vertical)

  • where M = N^2 (or N^2-1 if normalize=True, since DC is dropped).

Parameters:
Return type:

ndarray

Notes

  • If normalize=True, drop the DC component, mean-center each basis vector, then contrast-normalize using get_contrast_norms (via flow padding trick).

circle_bundles.optical_flow.get_predominant_dirs(patches)[source]

Predominant direction in RP^1 via PCA of (u_i, v_i) vectors across pixels.

Parameters:

patches ((N, 2*n^2))

Returns:

  • predom_dirs ((N,) angles in [0, pi))

  • ratios ((N,) directionality score in [0,1] ( (λ1-λ2)/λ1 ))

Return type:

Tuple[ndarray, ndarray]

circle_bundles.optical_flow.get_lifted_predominant_dirs(flow_patches, *, eps=1e-12)[source]

For each patch, find the pixel with largest flow magnitude and return its unit vector.

Parameters:
  • flow_patches ((N, 2*n^2))

  • eps (float)

Returns:

unit

Return type:

(N,2) unit vectors (zeros where magnitude is tiny)

circle_bundles.optical_flow.read_flo(file)[source]

Read a Middlebury/Sintel .flo optical flow file.

Returns:

flow

Return type:

(H, W, 2) float32 array

Parameters:

file (str | Path)

circle_bundles.optical_flow.sample_from_frame(flo_path, n_patches, *, d=3, rng=None)[source]

Sample n_patches random dxd optical flow patches from a .flo file.

Returns:

samples – [0 : d*d) : u components (flattened Fortran order) [d*d : 2*d*d) : v components [-2], [-1] : (row, col) top-left corner in the frame

Return type:

(n_patches, 2*d*d + 2) array

Parameters:
circle_bundles.optical_flow.get_patch_sample(flow_root, *, patches_per_frame=385, d=3, random_state=0)[source]

Sample patches_per_frame from every .flo file under flow_root//.flo.

Returns:

  • patch_df (DataFrame with columns [‘patch’,’row’,’column’,’scene’,’frame’]) – where ‘patch’ stores a 1D np.ndarray of length 2*d*d.

  • file_paths (list of lists of .flo Paths, grouped by scene folder order)

Parameters:
Return type:

Tuple[DataFrame, List[List[Path]]]

circle_bundles.optical_flow.preprocess_flow_patches(patch_df, *, hc_frac=0.2, max_samples=50000, k_list=(300,), random_state=42)[source]

Preprocess optical flow patches in patch_df.

Requires patch_df[‘patch’] to contain length-2*n^2 vectors.

Steps: - infer n - compute x/y mean - compute contrast norm + keep top hc_frac - downsample to max_samples - mean-center + contrast-normalize - compute density estimates 1 / dist_to_kNN for each k in k_list - sort by largest k density (descending)

Parameters:
Return type:

DataFrame

circle_bundles.optical_flow.make_patch_visualizer(*, fig_size=3.0, dpi=120, intensity_cmap='gray', intensity_normalize='minmax', show_intensity_grid=True, intensity_grid_lw=0.8, flipud=True, flow_normalize='maxmag', quiver_width=0.02, headwidth=5, headlength=5, grid_lw=7, border_lw_mult=2.0)[source]

Canonical patch visualizer.

  • intensity (n^2): uses imshow, optional grid overlay

  • flow (2*n^2): quiver arrows on grid, optional vertical flip for display convention

Return type:

vis_func(patch_vector) -> matplotlib Figure

Parameters: