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, dem=None)[source]
Inverse of bp_polar_range_dealias.
- Parameters:
img (Tensor) – Complex input image. Shape should be: [Range, azimuth] or [nbatch, 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.
dem (Tensor or None) – Digital elevation model sampled on the image polar grid. See
bp_polar_range_dealias(). Must be the same dem the image was dealiased with.
- 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, dem=None)[source]
De-alias range-axis spectrum of polar SAR image processed with backprojection. [1]
Equivalent to the
dealiasoption oftorchbp.ops.backprojection_polar_2d()whenoriginis the center of the platform positions used for backprojection ([0, 0, z0]when the positions were centered) and the samedemis given.- Parameters:
img (Tensor) – Complex input image. Shape should be: [Range, azimuth] or [nbatch, 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.
dem (Tensor or None) – Digital elevation model sampled on the image polar grid, same convention as the dem input of
torchbp.ops.backprojection_polar_2d(): float32 [dem_nr, dem_ntheta] covering the grid extent, can be coarser than the image grid (bilinearly interpolated). When given, the carrier is referenced to the pixel at the DEM height, matching the dealias carrier of a backprojection with the same dem. If None the carrier is referenced to the z=0 plane.
- 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)
dem (Tensor | None)
- 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
muis mean andstdis standard deviation ofabs(x)along dimensiondim.- Parameters:
x (Tensor) – Input tensor.
dim (int)
- Returns:
contrast – Calculated negative contrast of the input.
- Return type:
Tensor
- torchbp.util.conv_lowpass_filter(data, window_width)[source]
Time-domain lowpass filter: moving average with Hamming window taps along the last axis, with replicate edge padding.
Time-domain alternative to
fft_lowpass_filter_window(). Note the different parameter meaning:window_widthis the filter length in samples (cutoff at roughly1 / window_widthcycles per sample), while the FFT variant’s width is in frequency bins. Replicate padding avoids the edge roll-off that zero padding causes on short signals. Works for real and complex input.- Parameters:
data (Tensor) – Input tensor, filtered along the last axis.
window_width (int) – Filter length in samples. Lengths <= 1 (or longer than the signal) return the input unchanged.
- Returns:
filtered_data – Filtered tensor with the same shape as 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.dem_to_polar(dem, dem_grid, polar_grid, origin=None, rotation=0.0)[source]
Resample a Cartesian DEM onto a polar grid for use as the dem input of torchbp.ops.backprojection_polar_2d.
- Parameters:
dem (Tensor) – Cartesian DEM heights, shape [nx, ny] on dem_grid. Same x/y coordinate frame and z datum as the platform positions before subtracting origin.
dem_grid (CartesianGrid or dict) – Cartesian grid of dem.
polar_grid (PolarGrid or dict) – Polar grid to sample to. Should have the same r and theta extent as the imaging grid; nr and ntheta can be smaller for a downsampled DEM.
origin (Tensor or None) – Polar grid origin [x, y, z] in the DEM frame (the origin subtracted from the platform positions). Default is zeros.
rotation (float) – Polar grid rotation in radians, same convention as torchbp.ops.polar_to_cart.
- Returns:
dem_polar – DEM heights at the polar grid points relative to the origin z, shape [nr, ntheta] float32. Points outside the DEM extent take the nearest border value. Guard band points |theta| > 1 sample at the clamped angle.
- 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.diffimplemented 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 – Windowing Tensor.
- Return type:
Tensor
- Parameters:
data_length (int)
window_width (int)
device (str)
window (str | tuple)
circular_conv (bool)
fast_len (bool)
- 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 complex target reflectivity, used directly as the signal amplitude (same convention as the image input of torchbp.ops.projection_cart_2d).
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:
- 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:
- 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.polar_dem_slopes(dem, grid, theta_psi=False)[source]
Stack a polar-grid DEM with its Cartesian terrain slopes for the dem input of the tx_power kernels.
- Parameters:
dem (Tensor) – DEM heights on the polar grid, shape [dem_nr, dem_ntheta]. Covers the same r and theta extent as grid; the resolution can differ.
grid (PolarGrid or dict) – Polar grid giving the r and theta extents (nr and ntheta are taken from dem).
theta_psi (bool) – If True the theta axis is uniform in the angle psi (radians) instead of sin(psi). Used for the ffbp subaperture node grids.
- Returns:
dem3 – [3, dem_nr, dem_ntheta] float32 stack (z, dz/dx, dz/dy). The slopes are in the Cartesian frame of the grid origin and are translation invariant, so the same values apply in shifted subaperture frames.
- 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.taper_antenna_pattern(g, g_extent, az_margin, el_margin=0.0)[source]
Extend an antenna gain pattern with a raised-cosine roll-off to zero.
The backprojection kernels treat angles outside the pattern table as exactly zero gain, so a measured pattern that ends at its measurement extent with nonzero gain has a hard cutoff step there. When the table edge falls inside the scene, the step degrades algorithms that model the gain envelope as smooth: the
torchbp.ops.afbp()wavenumber fusion with per-pulse gain cannot represent the step (the accumulation dims and smears around the cutoff), and with platform yaw the step sweeps over the edge pixels, which also degrades the frozen-gainantenna_leaf_gain="subaperture"model oftorchbp.ops.ffbp(). Rolling the edge value off to zero over a margin removes the step; the taper region slightly underweights pixels there, consistently in both the accumulation and the illumination maps.- Parameters:
g (Tensor) – Antenna gain pattern, shape [g_nel, g_naz].
g_extent (list) – Pattern extent [g_el0, g_az0, g_el1, g_az1] in radians.
az_margin (float) – Azimuth roll-off width in radians, added on both sides. Rounded to whole table cells; 0 disables.
el_margin (float) – Same for the elevation axis. Default 0.
- Returns:
(g, g_extent) – Extended pattern and its extent, same cell size as the input.
- Return type:
tuple[Tensor, list]
- torchbp.util.unwrap(phi, dim=-1)[source]
np.unwrapimplemented 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.weighted_detrend(x, w)[source]
Removes weighted linear trend.
The removed line is the weighted least squares fit, so samples with zero weight do not affect the fit but the line is still subtracted over the whole tensor. Degenerate weights (all zero or concentrated on one sample) remove only the weighted mean.
- Parameters:
x (Tensor) – Input tensor. Should be 1 dimensional.
w (Tensor or None) – Non-negative per-sample weights with the same shape as
x. None falls back to the unweighteddetrend().
- Returns:
x – x with weighted linear trend removed.
- 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_powerinverts 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 normalizationsar / tx_power; where it is weak the gain rolls off astx_power**2so the output goes to zero instead of amplifying noise. The SNR map itself is(tx_power / eps)**2.The regularization
epsis 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 oftx_power).- Parameters:
sar (Tensor) – Complex or magnitude SAR image. 2D
(nr, ntheta)or 3D(nbatch, nr, ntheta).tx_power (Tensor) – Illumination map from
torchbp.ops.backprojection_polar_2d_tx_power()(square root of power returned for unit reflectivity), real-valued with the same number of dimensions assar. Its trailing two dimensions may be coarser thansar; if so it is bilinearly interpolated up tosar’s grid on the fly (viatorchbp.ops.mul_2d_interp_linear()/torchbp.ops.div_2d_interp_linear()) so no full-resolution map is allocated. 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_powerunits. 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 brightestcalib_quantilefraction 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
epswhen it is not given. Default 0.1 (dimmest/brightest 10%).
- Returns:
s_hat – Normalized image, same dtype as
sar.- Return type:
Tensor