sidescanpy.analysis.shadows#
Object proposals from acoustic shadows in native slant-range data.
An object standing proud of the seabed returns a highlight on its
near-range face and leaves a shadow (little or no return) behind it,
further out along the same pings. detect_shadow_proposals() finds
those shadows as regions well below the local seabed level, pairs each
with the highlight just in front of it, and returns one proposal box per
object in native (ping, sample, channel) coordinates, with features
(sizes, contrast, an estimated height) to rank or filter them.
The data are averaged into cells about cell_m across track (one ping
along track) before thresholding, because single samples carry several
dB of speckle. A second, weaker threshold catches the short, shallow
shadows of objects close to nadir, where the grazing angle is steep; those
regions are kept only with a highlight in front of them. Proposals are
meant to pre-fill boxes for a person to correct, so the defaults favour
recall over precision.
2026 rshomberg@uri.edu
Contents
Built-in mutable sequence. |
|
Proposals found by |
|
Find objects by their acoustic shadow. |
- sidescanpy.analysis.shadows.PROPOSAL_COLUMNS#
Built-in mutable sequence.
If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.
- class sidescanpy.analysis.shadows.ShadowProposals(proposals=<factory>, m_per_ping=None, m_per_sample=None, cell_samples=None, params=<factory>, n_shadow_regions=0, n_rejected=<factory>, notes=<factory>)#
Bases:
Proposals found by
detect_shadow_proposals().proposalshas one row per proposal (columnsPROPOSAL_COLUMNS). Extents are half-open native positions along the dataset’spingandsampleaxes, likeNativeWindow; the box spans the highlight (when found) and the shadow.height_mis NaN where altitude is unknown.weakmarks proposals from the weak-shadow pass.scoreis in[0, 1]: higher for a deeper shadow, a taller object (a longer shadow where altitude is unknown) and a highlight in front.
- sidescanpy.analysis.shadows.detect_shadow_proposals(ds, *, value_var='backscatter_intensity', channels=(0, 1), cell_m=0.06, background_m=(3.0, 6.0), smooth_cells=(1, 3), shadow_db=6.0, highlight_db=3.0, min_shadow_m=0.2, min_pings=2, max_gap_m=0.6, highlight_search_m=2.0, min_height_m=0.0, max_height_m=3.0, max_length_m=8.0, weak_shadow_db=4.0, weak_min_shadow_m=0.1, weak_min_highlight=0.5, score_height_m=0.3, m_per_ping=None, mask_water_column=True)#
Find objects by their acoustic shadow.
For each channel:
Average
value_var(dB, after thetvgstep) into cells of aboutcell_malong range, one ping each, then smooth them with asmooth_cells(pings, cells) running mean.Background: a running median over
background_m(across, along track, metres).Shadow cells are at least
shadow_dbbelow the background; they are grouped into connected regions (8-connected).A region is kept if it covers at least
min_pingspings and its longest run along range is at leastmin_shadow_m.Its highlight is the run of cells at least
highlight_dbabove the background ending withinmax_gap_mbefore the shadow, searched up tohighlight_search_mtowards nadir, on each of its pings.Height from flat-seabed geometry,
h = A * Ls / (R + Ls)(altitudeA, slant rangeRto the shadow start, shadow slant lengthLs), per ping, median over the region. Proposals outside[min_height_m, max_height_m](when the height is known) or longer thanmax_length_min either direction are dropped.Weak pass (unless
weak_shadow_dbis None): regions at leastweak_shadow_dbbelow the background that contain no cell of a proposal from steps 3-6, with a run of at leastweak_min_shadow_m, go through steps 4-6 and are kept when a highlight is found on at leastweak_min_highlightof their pings. They getweak=True.
score= 0.4 x shadow depth (shadow_db-> 0,3 * shadow_db-> 1) + 0.3 x height /score_height_m(capped at 1; shadow length / 1 m where the height is unknown) + 0.3 x the fraction of pings with a highlight. Height rather than shadow length, because the shadow of the same object is much shorter near nadir.The water column is excluded: with
mask_water_column(default), samples at a slant range up to the ping’s altitude (sample * m_per_sample <= altitude_m, the same flat-seabed geometry as the height estimate) are treated as NaN, because they come before the first bottom return and their low level reads as many weak false shadows. Pings with NaN or non-positivealtitude_m(or a dataset without it) are not masked; fill missing altitude first with thebottom_trackcorrection step.dsis not modified.NaN cells (blanked or masked water column, hull echo, masked pings) are never shadow, and a region whose near-range side lies within 0.3 m of NaN cells on most of its pings is dropped: that is the edge of the blanked area, not an object.
- Parameters:
- dsxr.Dataset
One frequency channel (slice pings beforehand to limit memory).
- value_varstr, default “backscatter_intensity”
Values in dB.
- channelstuple of int, default (0, 1)
- cell_mfloat, default 0.06
Across-track cell size; rounded to a whole number of samples.
- background_m(float, float), default (3.0, 6.0)
Background window, across track and along track (m).
- smooth_cells(int, int), default (1, 3)
Running-mean size (pings, cells) applied before thresholding.
- shadow_db, highlight_dbfloat, default 6.0, 3.0
Thresholds below / above the background (dB).
- min_shadow_mfloat, default 0.2
- min_pingsint, default 2
- max_gap_mfloat, default 0.6
- highlight_search_mfloat, default 2.0
- min_height_m, max_height_mfloat, default 0.0, 3.0
- max_length_mfloat, default 8.0
- weak_shadow_dbfloat or None, default 4.0
Threshold of the weak pass (dB below background); None skips it.
- weak_min_shadow_mfloat, default 0.1
- weak_min_highlightfloat, default 0.5
Fraction of a weak region’s pings that must have a highlight.
- score_height_mfloat, default 0.3
Height that earns the full height part of the score.
- m_per_pingfloat, optional
Along-track spacing; default from the per-ping positions.
- mask_water_columnbool, default True
Treat samples with slant range <=
altitude_mas NaN (see above). False uses every sample as given.
- Returns:
- ShadowProposals