Drop a video here or click to browse
MP4 · M4V · MOV · WebM · AVI · MKV · MPEG
Video ROI tracking · individual & paired modes · scientific-grade analytics
Rianu2 tracks regions of interest through a video and measures how they move over time — peak motion, beat rate, timing, and distances between points.
If you use Rianu2 in your research, please cite:
Every numerical quantity reported by Rianu2 is documented below.
Section numbers (§1, §2, …) reference static/calculations.js,
which contains the authoritative implementations.
The centre of the tracked bounding box on each frame, in original video coordinates (independent of any crop). Sub-pixel because we use the box's half-width and half-height as floats.
cx = roi_x + roi_w / 2 cy = roi_y + roi_h / 2Position of the tracked box on this frame. The width and height are fixed at initialisation and never change.
True when the tracker's internal confidence score for this frame exceeded its algorithm-specific threshold. The centroid is still reported when ok = false (it's the best current estimate).
Euclidean distance from the centroid on the very first frame to the centroid on this frame. This is the primary kinematic signal used for ROI analysis.
motion(t) = √( (cx(t) − cx(0))² + (cy(t) − cy(0))² )Computed once per ROI per frame in the tracking worker (main.py).
The largest motion value observed for this ROI from
the start of tracking to the current frame.
Euclidean distance between the two centroids of pair k on the current frame. Stored as an array, one entry per pair.
dists[k] = √( (cx_B − cx_A)² + (cy_B − cy_A)² )where A is ROI 2k and B is ROI 2k+1.
For each sample, a polynomial of degree polyOrder is
fit (least squares) to the windowLength samples
centred on it; the fitted value at the centre becomes the smoothed
output. The convolution coefficients are the first row of
(XᵀX)⁻¹Xᵀ, where X is the Vandermonde matrix of centred offsets.
Edge samples use replicate boundary (clamp to [0, n−1]),
matching scipy's mode='nearest'. Defaults in the UI:
windowLength = 13, polyOrder = 3.
calculations.js §1
The baseline estimate at sample i is the minimum value
within a symmetric window of win frames centred on
i. The window is clipped at the array boundaries.
Subtract the rolling-min baseline and clip at zero. Any value greater than the local minimum is treated as signal-above-baseline.
out[i] = max(0, data[i] − baseline[i])This is a standard nonlinear baseline estimator for impulsive signals — it removes slow drift while preserving peak shape.
For recordings whose feature of interest is a downward deflection (a trough) rather than an upward peak, enabling Invert Signal reflects the signal so the peak detector can find it. The reflection is around the signal's own maximum, which keeps the output non-negative — the deepest trough becomes the tallest peak.
out[i] = max(data) − data[i]Applied first in the pipeline (raw → invert → Savitzky–Golay → baseline removal). Being an affine transform it commutes with smoothing. All downstream metrics (peaks, beat rate, slopes, timing) are then computed on the inverted signal.
Pass 1 — candidates: local maxima with strict > on both neighbours; flat-topped plateaus (created by smoothing) are reported at their midpoint sample.
Pass 2 — topographic prominence: walk outward from each candidate tracking the running minimum until a strictly higher sample is reached. Prominence is the candidate's height above the higher of the two "key cols" found this way.
prominence = peakValue − max(leftKeyCol, rightKeyCol)Candidates failing prominence ≥ minPromFrac × signalRange
are discarded. This matches the definition used by
scipy.signal.peak_prominences.
Pass 3 — base positions: for each surviving peak,
the start (leftBaseIdx) is the index of the minimum value
between the previous surviving peak's apex (or trim start) and this
apex. The end (rightBaseIdx) is the minimum between
this apex and the next surviving peak's apex (or trim end). This
prevents the start/end from skipping past adjacent peaks and stays
robust to small noise dips near the apex.
The percent value in the UI is divided by 100 and applied as a fraction of the in-trim signal range. So a slider value of 5 means: a candidate must rise at least 5 % of (max − min) above its higher key col to be reported.
Baseline is the average of the values at the peak's start and end. Amplitude is the peak's apex value above that baseline.
base = (leftBaseVal + rightBaseVal) / 2 ampl = peakValue − baseTopographic prominence as defined in §3, i.e. apex value minus the higher of the two key-col minima.
Constant absolute levels per peak. Used as crossings for the timing metrics below and drawn as dashed horizontal lines on the chart.
level10 = base + 0.10 × ampl level50 = base + 0.50 × amplTime from the rising 10 % crossing to the apex.
t2pk = apexTime − t10RiseTimeThe 10 % crossing time is found by linear interpolation between the two adjacent samples that bracket level10, scanning backwards from the apex (i.e. the last upward crossing — robust to noise on the foot).
Time from the apex to the falling 10 % crossing.
t2rel = t10FallTime − apexTimeTime from the apex to the falling 50 % crossing.
t2rel50 = t50FallTime − apexTimeMaximum central-difference derivative between the peak's start
and apex. In calibrated mode the label becomes d(mm)/dt.
When this peak is selected on the chart, a dotted tangent line through the corresponding sample is drawn.
Most negative central-difference derivative between the apex and the peak's end. Always ≤ 0.
minSlope = min over j in [globalIdx, rightBaseIdx] of slope(j)Reciprocal of the mean inter-peak interval — equivalent to total beats divided by total observed time.
meanFreq = 1 / mean(intervals)Requires ≥ 2 peaks. Subtitle on the card shows
s/beat (the mean interval itself) and the peak count.
Standard deviation of the per-interval frequency, divided by the mean of the per-interval frequencies. Reported as a percentage. Captures interval-to-interval variability that the mean alone hides.
stdFreq = √( mean( (freq − mean(freq))² ) ) ← population σ covFreq = stdFreq / mean(freq) BR COV = 100 × covFreq [%]Population variance (divide by N, not N−1) — we are summarising the beats actually observed, not estimating a population parameter from a draw. Requires ≥ 3 peaks (≥ 2 intervals).
Maximum of the raw motion signal for this ROI within
its trim range. Subtitle gives the frame and time at which the
maximum occurs.
Identical to the calculations.js §5 formulas above, applied to the peaks detected on this ROI's processed signal (using the metric currently displayed for the active ROI, motion otherwise).
Span of the processed pair-distance signal across the pair's trim range — i.e. how much the centroid-to-centroid distance varies. Subtitle gives the min and max values and the frames they occur on.
maxMotion = max(processedDists in trim) − min(processedDists in trim)"Processed" means after Savitzky–Golay and optional baseline removal, using the pair's own settings.
Same definitions as above (calculations.js §5), applied to the peaks detected on the pair's processed distance signal.
Optional. Drawing a calibration line over a known length stores
pxPerMm. All linear quantities convert as
mm = px / pxPerMm. The conversion is linear, so it
commutes with smoothing, baseline removal, and peak detection —
filters are applied in pixel space and converted at display time.
Slopes follow the same rule: mm/s = (px/s) / pxPerMm.
Drop a video here or click to browse
MP4 · M4V · MOV · WebM · AVI · MKV · MPEG