torchbp.util module

torchbp.util.argmax_nd(x)[source]

torch.argmax but returns N-dimensional index of the peak

Parameters:

x (Tensor)

Return type:

tuple[int, …]

torchbp.util.bounding_cart_grid(grid_polar, origin, origin_angle)[source]

Return the bounding Cartesian grid for polar input grid.

Parameters:
  • grid_polar (PolarGrid or dict) –

    Polar grid definition. Can be:

    • PolarGrid object: PolarGrid(r_range=(r0, r1), theta_range=(theta0, theta1), nr=nr, ntheta=ntheta)

    • dict: {“r”: (r0, r1), “theta”: (theta0, theta1), “nr”: nr, “ntheta”: ntheta}

    where theta is sin of angle (-1, 1 for 180 degree view).

  • origin (tuple) – Origin coordinates of grid_polar in the Cartesian grid.

  • origin_angle (float) – Reference direction (radians) that corresponds to s = 0.

Returns:

(xmin, ymin, xmax, ymax) – Coordinates of the smallest axis‑aligned rectangle containing the grid.

Return type:

tuple[float, float, float, float]

torchbp.util.bp_polar_range_alias(img, origin, fc, grid_polar, alias_fmod=0)[source]

Inverse of bp_polar_range_dealias.

Parameters:
  • img (Tensor) – Complex input image. Shape should be: [Range, azimuth].

  • origin (Tensor) – Center of the platform position.

  • fc (float) – RF center frequency.

  • grid_polar (PolarGrid or dict) –

    Polar grid definition. Can be:

    • PolarGrid object: PolarGrid(r_range=(r0, r1), theta_range=(theta0, theta1), nr=nr, ntheta=ntheta)

    • dict: {“r”: (r0, r1), “theta”: (theta0, theta1), “nr”: nr, “ntheta”: ntheta}

  • alias_fmod (float) – Range modulation frequency applied to output.

Returns:

img – SAR image with range spectrum aliasing.

Return type:

Tensor

torchbp.util.bp_polar_range_dealias(img, origin, fc, grid_polar, alias_fmod=0)[source]

De-alias range-axis spectrum of polar SAR image processed with backprojection. [1]

Parameters:
  • img (Tensor) – Complex input image. Shape should be: [Range, azimuth].

  • origin (Tensor) – Center of the platform position.

  • fc (float) – RF center frequency.

  • grid_polar (PolarGrid or dict) –

    Polar grid definition. Can be:

    • PolarGrid object: PolarGrid(r_range=(r0, r1), theta_range=(theta0, theta1), nr=nr, ntheta=ntheta)

    • dict: {“r”: (r0, r1), “theta”: (theta0, theta1), “nr”: nr, “ntheta”: ntheta}

  • alias_fmod (float) – Range modulation frequency applied to input.

Return type:

Tensor

References

[1]

T. Shi, X. Mao, A. Jakobsson and Y. Liu, “Extended PGA for Spotlight SAR-Filtered Backprojection Imagery,” in IEEE Geoscience and Remote Sensing Letters, vol. 19, pp. 1-5, 2022, Art no. 4516005.

Returns:

img – SAR image without range spectrum aliasing.

Return type:

Tensor

Parameters:
  • img (Tensor)

  • origin (Tensor)

  • fc (float)

  • grid_polar (PolarGrid | dict)

  • alias_fmod (float)

torchbp.util.center_pos(pos)[source]

Center position to origin. Centers X and Y coordinates, but doesn’t modify Z. Useful for preparing positions for polar backprojection

Parameters:

pos (Tensor) – 3D positions. Shape should be [N, 3].

Returns:

  • pos_local (Tensor) – Centered positions.

  • origin (Tensor) – Position subtracted from the pos.

Return type:

tuple[Tensor, Tensor]

torchbp.util.contrast(x, dim=-1)[source]

Calculates negative contrast:

-mean(std/mu)

where mu is mean and std is standard deviation of abs(x) along dimension dim.

Parameters:
  • x (Tensor) – Input tensor.

  • dim (int)

Returns:

contrast – Calculated negative contrast of the input.

Return type:

Tensor

torchbp.util.create_triangular_weights(patch_size, overlap, device='cpu')[source]

Create triangular weights for smooth blending of overlapping patches.

Parameters:
  • patch_size (int) – Side length of patches.

  • overlap (int) – Overlap between patches.

  • device (str) – Pytorch device.

Returns:

weights_2d – Weight tensor of [patch_size, patch_size] with triangular weighting

Return type:

Tensor

torchbp.util.detrend(x)[source]

Removes linear trend

Parameters:

x (Tensor) – Input tensor. Should be 1 dimensional.

Returns:

x – x with linear trend removed.

Return type:

Tensor

torchbp.util.diff(x, dim=-1, same_size=False)[source]

np.diff implemented in torch.

Parameters:
  • x (Tensor) – Input tensor.

  • dim (int) – Dimension.

  • same_size (bool) – Pad output to same size as input.

Returns:

d – Difference tensor.

Return type:

Tensor

torchbp.util.entropy(x)[source]

Calculates entropy:

-sum(y*log(y))

where y = abs(x) / sum(abs(x)).

Parameters:

x (Tensor) – Input tensor.

Returns:

entropy – Calculated entropy of the input.

Return type:

Tensor

torchbp.util.extract_overlapping_patches(img, patch_size, overlap)[source]

Extract overlapping patches from a tensor.

Parameters:
  • img (Tensor) – Input tensor of shape [C, N, M].

  • patch_size (int) – Side length of square patches (K).

  • overlap (int) – Overlap between patches.

Returns:

  • patches (Tensor) – Tensor of shape [C, P, K, K] where P is the number of patches.

  • dim (tuple) – Original image dimensions.

Return type:

tuple[Tensor, tuple[int, …]]

torchbp.util.fft_lowpass_filter_precalculate_window(data_length, window_width, device, window, circular_conv=False, fast_len=True)[source]

Precompute window to be used with fft_lowpass_filter_window.

Returns:

  • w (Tensor) – Windowing Tensor.

  • pad_size (int) – Amount of padding added to signal (needed for extraction).

Parameters:
  • data_length (int)

  • window_width (int)

  • device (str)

  • window (str | tuple)

  • circular_conv (bool)

  • fast_len (bool)

Return type:

Tensor

torchbp.util.fft_lowpass_filter_window(target_data, window='hamming', window_width=None, circular_conv=False, fast_len=True)[source]

FFT low-pass filtering with a configurable window function.

Parameters:
  • target_data (Tensor)

  • window (str | tuple | Tensor)

  • window_width (int)

  • circular_conv (bool)

  • fast_len (bool)

Return type:

Tensor

torchbp.util.fft_peak_1d(x, dim=-1, fractional=True)[source]

Find fractional peak of abs(fft(x)).

Parameters:
  • x (Tensor) – Input tensor.

  • dim (int) – Dimension to calculate peak.

  • fractional (bool) – Estimate peak location with fractional index accuracy.

Returns:

a – Estimated peak index.

Return type:

int or float

torchbp.util.find_image_shift_1d(x, y, dim=-1)[source]

Find shift between images that maximizes correlation.

Parameters:
  • x (Tensor) – Input tensor.

  • y (Tensor) – Input tensor. Should have same shape as x.

  • dim (int) – Dimensions to shift.

Returns:

c – Estimated shift.

Return type:

Tensor

torchbp.util.find_image_shift_2d(x, y, dim=(-2, -1), interpolate=False)[source]

Find shift between images that maximizes correlation.

Parameters:
  • x (Tensor) – Input tensor.

  • y (int) – Input tensor. Should have same shape as x.

  • dim (tuple) – Dimension.

Returns:

  • c (tuple) – Estimated shift.

  • a (float) – Peak of correlation.

Return type:

tuple

torchbp.util.generate_fmcw_data(target_pos, target_rcs, pos, fc, bw, tsweep, fs, d0=0, g=None, g_extent=None, att=None, rvp=True, vel=None)[source]

Generate FMCW radar time-domain IF signal.

Parameters:
  • target_pos (Tensor) – [ntargets, 3] tensor of target XYZ positions.

  • target_rcs (Tensor) – [ntargets, 1] tensor of target reflectivity.

  • pos (Tensor) – [nsweeps, 3] tensor of platform positions. When vel is provided, pos[s] is the platform position at the midpoint of sweep s.

  • fc (float) – RF center frequency in Hz.

  • bw (float) – RF bandwidth in Hz.

  • tsweep (float) – Length of one sweep in seconds.

  • fs (float) – Sampling frequency in Hz.

  • d0 (float) – Zero range.

  • g (Tensor or None) – Square-root of two-way antenna gain in spherical coordinates, shape: [elevation, azimuth]. If TX antenna equals RX antenna, then this should be just antenna gain. (0, 0) angle is at the beam center. Isotropic antenna is assumed if g is None.

  • g_extent (list or None) – List of [g_el0, g_az0, g_el1, g_az1]. g_el0, g_el1 are grx and gtx elevation axis start and end values. Units in radians. -pi/2 + +pi/2 if including data over the whole sphere. g_az0, g_az1 are grx and gtx azimuth axis start and end values. Units in radians. -pi to +pi if including data over the whole sphere.

  • att (Tensor) – Euler angles of the radar antenna at each data point. Shape should be [nsweeps, 3]. [Roll, pitch, yaw]. Only roll and yaw are used at the moment.

  • rvp (bool) – True to include residual video phase term.

  • vel (Tensor or None) – [nsweeps, 3] tensor of platform velocities in m/s. When given, the two-way delay is evaluated per intra-sweep sample at the instantaneous platform position pos[s] + vel[s] * (t_sample - tsweep/2), i.e. the stop-and-go approximation is removed. None (default) reproduces the stop-and-go model where pos[s] is held fixed across the chirp.

Returns:

data – [nsweeps, nsamples] measurement data.

Return type:

Tensor

torchbp.util.make_polar_grid(r0, r1, nr, ntheta, theta_limit=1, squint=0)[source]

Generate PolarGrid object.

Parameters:
  • r0 (float) – Minimum range in m.

  • r1 (float) – Maximum range in m.

  • nr (float) – Number of range points.

  • ntheta (float) – Number of azimuth points.

  • theta_limit (float) – Theta axis limits, symmetrical around zero. Units are sin of angle (0 to 1 valid range). Default is 1.

  • squint (float) – Grid azimuth mean angle, radians.

Returns:

grid_polar – Polar grid object.

Return type:

PolarGrid

torchbp.util.make_polar_grid_obj(r0, r1, nr, ntheta, theta_limit=1, squint=0)

Generate PolarGrid object.

Parameters:
  • r0 (float) – Minimum range in m.

  • r1 (float) – Maximum range in m.

  • nr (float) – Number of range points.

  • ntheta (float) – Number of azimuth points.

  • theta_limit (float) – Theta axis limits, symmetrical around zero. Units are sin of angle (0 to 1 valid range). Default is 1.

  • squint (float) – Grid azimuth mean angle, radians.

Returns:

grid_polar – Polar grid object.

Return type:

PolarGrid

torchbp.util.merge_patches_with_triangular_weights(patches, original_shape, patch_size, overlap, padded_shape=None)[source]

Merge overlapping patches back into an image using triangular weighting.

Parameters:
  • patches (Tensor) – Tensor of shape [C, P, K, K] containing patches

  • original_shape (tuple) – Original shape of the image (N, M).

  • patch_size (int) – Side length of square patches (K).

  • overlap (int) – Overlap between patches.

  • padded_shape (tuple) – Tuple (N_pad, M_pad) of padded dimensions.

Returns:

img – Reconstructed image tensor of shape [C, N, M].

Return type:

Tensor

torchbp.util.next_fast_len(n)[source]

CuFFT-friendly length (powers of 2,3,5,7)

Parameters:

n (int)

Return type:

int

torchbp.util.phase_to_distance(p, fc)[source]

Convert radar reflection phase shift to distance.

Parameters:
  • p (Tensor) – Phase shift tensor.

  • fc (float) – RF center frequency.

Return type:

Tensor

torchbp.util.process_image_with_patches(img, patch_size, overlap, process_fn)[source]

Process an image by extracting patches, applying a function, and merging back.

Parameters:
  • img (Tensor) – Input tensor of shape [C, N, M] or [N, M].

  • patch_size (int) – Side length of square patches.

  • overlap (int) – Overlap between patches.

  • process_fn (function) – Function to apply to patches.

Returns:

img – Processed image with same shape as the input.

Return type:

Tensor

torchbp.util.quad_interp(a, v)[source]

Quadractic peak interpolation. Useful for FFT peak interpolation.

Parameters:
  • a (Tensor) – Input tensor.

  • v (int) – Peak index.

Returns:

f – Estimated fractional peak index.

Return type:

Tensor

torchbp.util.shift_spectrum(x, dim=-1)[source]

Equivalent to: fft(ifftshift(ifft(x, dim), dim), dim), but avoids calculating FFTs.

Parameters:
  • x (Tensor) – Input tensor.

  • dim (int)

Returns:

y – Shifted tensor.

Return type:

Tensor

torchbp.util.subset_cart(img, grid_cart, x0, x1, y0, y1)[source]

Cartesian image subset.

Parameters:
  • img (Tensor) – Input image.

  • grid_cart (CartesianGrid or dict) –

    Cartesian grid definition. Can be:

    • CartesianGrid object: CartesianGrid(x_range=(x0, x1), y_range=(y0, y1), nx=nx, ny=ny)

    • dict: {“x”: (x0, x1), “y”: (y0, y1), “nx”: nx, “ny”: ny}

  • x0 (float) – Subset x0.

  • x1 (float) – Subset x1.

  • y0 (float) – Subset y0.

  • y1 (float) – Subset y1.

Returns:

  • img (Tensor) – Subset of input image.

  • grid (dict) – Grid

Return type:

tuple[Tensor, dict]

torchbp.util.subset_polar(img, grid_polar, r0, r1, theta0, theta1)[source]

Polar image subset.

Parameters:
  • img (Tensor) – Input image.

  • grid_polar (PolarGrid or dict) – Polar grid definition. PolarGrid object or dictionary.

  • r0 (float) – Subset r0.

  • r1 (float) – Subset r1.

  • theta0 (float) – Subset theta0.

  • theta1 (float) – Subset theta1.

Returns:

  • img (Tensor) – Subset of input image.

  • grid_new (dict) – Grid.

Return type:

tuple[Tensor, dict]

torchbp.util.unwrap(phi, dim=-1)[source]

np.unwrap implemented in torch.

Parameters:
  • phi (Tensor) – Input tensor.

  • dim (int) – Dimension.

Returns:

phi – Unwrapped tensor.

Return type:

Tensor

torchbp.util.unwrap_ref(x, y)[source]

Solve for integer array k such that x + k*2pi is closest to y. k = round((y - x) / (2pi)).

Parameters:
  • x (Tensor) – Phase wrapped signal.

  • y (Tensor) – Reference signal.

Returns:

unwrapped_x – Phase unwrapped x

Return type:

Tensor

torchbp.util.wiener_normalize(sar, tx_power, eps=None, calib_quantile=0.1)[source]

SNR-aware radiometric normalization of a SAR image by an illumination map.

Plain division sar / tx_power inverts the illumination, but where the illumination is weak (swath edges, antenna nulls) it divides receiver noise by a near-zero number and the result blows up. This applies the Wiener (MMSE) estimate instead:

\[\hat{s} = \frac{\mathrm{sar}\cdot\mathrm{tx\_power}} {\mathrm{tx\_power}^2 + \varepsilon^2}\]

which equals (sar / tx_power) * SNR / (1 + SNR) with the per-pixel power SNR = (tx_power / eps)**2. Where the illumination is strong it reduces to the full normalization sar / tx_power; where it is weak the gain rolls off as tx_power**2 so the output goes to zero instead of amplifying noise. The SNR map itself is (tx_power / eps)**2.

The regularization eps is the noise-to-signal amplitude ratio \(\varepsilon = \sigma_n / \sigma_s\) in tx_power units, where \(\sigma_n\) is the additive noise amplitude in the image and \(\sigma_s\) is the reflectivity scale relating image to illumination (sar = s * tx_power + n). It is the illumination level at which the SNR equals one. Note this is not simply the noise level \(\sigma_n\): it must be divided by the reflectivity scale (which also absorbs the leftover radiometric calibration constant of tx_power).

Parameters:
  • sar (Tensor) – Complex or magnitude SAR image, same pseudo-polar shape as tx_power.

  • tx_power (Tensor) – Illumination map from torchbp.ops.backprojection_polar_2d_tx_power() (square root of power returned for unit reflectivity). Non-finite entries (un-illuminated pixels) are treated as no-data and mapped to zero.

  • eps (float or None) – Regularization level \(\sigma_n / \sigma_s\) in tx_power units. If None it is estimated from the data using the identity \(E|\mathrm{sar}|^2 = \sigma_s^2\,\mathrm{tx\_power}^2 + \sigma_n^2\): \(\sigma_s^2\) from the brightest calib_quantile fraction of pixels and \(\sigma_n^2\) from the dimmest fraction (with the residual signal subtracted). For real data prefer passing an explicit value from a known shadow region and a calibration target.

  • calib_quantile (float) – Fraction (0-0.5) of pixels at each illumination extreme used to estimate eps when it is not given. Default 0.1 (dimmest/brightest 10%).

Returns:

s_hat – Normalized image, same dtype as sar.

Return type:

Tensor