Lacunarity Analysis - CFAImageLAC

Gliding and non-overlapping box lacunarity with integral image speedup

Application Scenarios

Usage Examples

Basic Usage

import cv2 from FreeAeonFractal.FAImageLAC import CFAImageLAC from FreeAeonFractal.FAImage import CFAImage gray_image = cv2.imread('./images/fractal.png', cv2.IMREAD_GRAYSCALE) bin_image, threshold = CFAImage.otsu_binarize(gray_image) # Gliding box lacunarity calc = CFAImageLAC(bin_image, partition_mode="gliding") lac_result = calc.get_lacunarity(use_binary_mass=True, include_zero=True) fit_result = calc.fit_lacunarity(lac_result) print("Lambda(r):", lac_result['lacunarity']) print("Slope (beta):", fit_result['slope']) calc.plot(lac_result, fit_result)

GPU Accelerated Version

from FreeAeonFractal.FAImageLACGPU import CFAImageLACGPU calc = CFAImageLACGPU(bin_image, device='cuda') lac_result = calc.get_lacunarity()

Batch Processing

import glob, cv2 from FreeAeonFractal.FAImageLAC import CFAImageLAC images = [cv2.imread(f, cv2.IMREAD_GRAYSCALE) for f in glob.glob('./images/*.png')] batch_results = CFAImageLAC.get_batch_lacunarity( images, partition_mode="gliding", use_binary_mass=True) batch_fits = CFAImageLAC.fit_batch_lacunarity(batch_results) for fit in batch_fits: print("Slope:", fit['slope'])

Class Description

CFAImageLAC

Lacunarity calculator for a single 2D image. For batch processing use static methods get_batch_lacunarity / fit_batch_lacunarity.

Initialization Parameters

ParameterTypeDefaultDescription
imagenumpy.ndarrayRequired2D single-channel image
max_sizeintNoneMaximum box size
max_scalesint100Target number of scales
with_progressboolTrueShow progress bar
scales_modestr"powers""powers" (2,4,8,...) or "logspace"
partition_modestr"gliding""gliding" or "non-overlapping"
min_sizeint2Minimum box size

get_lacunarity(corp_type=-1, use_binary_mass=False, include_zero=True)

Compute Λ(r) for all scales. Λ(r) = E[M²] / E[M]². Returns dict with scales, lacunarity, mass_stats.

fit_lacunarity(lac_result, transform="log", fit_range=None)

Log-log regression. transform="log": fit log(Λ) vs log(r), slope = −β. transform="log_minus_1": legacy mode. Returns dict with slope, intercept, r_value, p_value, std_err.

plot(lac_result, fit_result=None, ...)

Visualize Λ(r) curve on log-log scale, and optionally the linear fit panel.

get_batch_lacunarity(images, ...) [static]

Batch lacunarity. Same-shape gliding batches are vectorized across all images at once.

fit_batch_lacunarity(lac_results, ...) [static]

Apply same fit to all batch results.

Algorithm Description

Lacunarity Definition

Λ(r) = E[M²] / E[M]² = 1 + Var(M) / Mean(M)²

Lower bound 1 = uniform. Larger Λ = stronger spatial heterogeneity.

Gliding Box — Integral Image

M(y, x) = S[y+r, x+r] - S[y, x+r] - S[y+r, x] + S[y, x]

Summed-area table computed once outside the scale loop. This is an N-scale speedup vs per-scale recomputation.

Lacunarity Scaling

For self-similar fractals: Λ(r) ~ r^{−β} with β = D − E. Default transform="log" reports slope = −β.

Important Notes

  1. Partition Mode: "gliding" is more robust; "non-overlapping" enforces sample independence
  2. Binary vs Gray: use_binary_mass=True for classic binary lacunarity (Allain & Cloitre 1991)
  3. Interpretation: Λ=1 → uniform; Λ>1 → gaps/clustering; larger = more heterogeneous

References