Skip to content

MGT-python 1.11.4

Choose a tag to compare

@alexarje alexarje released this 22 Aug 12:59
· 259 commits to master since this release

Fixed

  • The frame rate is no longer truncated to an integer. Seven call sites read
    int(vidcap.get(cv2.CAP_PROP_FPS))_directograms, _flow (twice), _history,
    _impacts, _warp and _videoadjust. On NTSC-rate footage that is int(29.97) == 29, so
    every time and frequency they derived was 3.2 % low, and _flow and _history also wrote
    the truncated value into the output file's declared rate, turning a 29.97 fps input into a
    29 fps file. The docs carried this as a known defect; it is fixed and the note now says so.

    Every use was checked to be safe with a non-integer rate: divisions, cv2.VideoWriter,
    ffmpeg -r and librosa sr all take a float, and _impacts already wrapped int() where
    it needed a whole number. Figures produced before this change are not comparable with
    figures produced after it on non-integer-rate footage.

  • Averaged frames are ROUNDED rather than truncated. Every averaging path finished with
    (acc / n).astype(np.uint8), which discards the fractional part instead of rounding it.
    On a synthetic stack the result sits 0.497 levels below the true mean and half the pixels
    differ by one from the rounded answer, always downward — a small, systematic bias in a
    frame whose purpose is to be a clean background to subtract. Seven places in four files:
    _spacetime._average_frame, _heatmap, the three pose average frames, and the two
    motiongram row and column means. _remap360 already rounded, which is where the
    convention came from.

    Output pixel values may therefore change by one level. Nothing about the API changes.

    Pinned by two tests in tests/test_average.py, because the existing suite passed either
    way: that truncation is strictly below the true mean where rounding is not, and a guard
    that reads the package for any accumulator divided by a count and cast without rounding.