Meter Measurements

helios.meter measures the path between a current point and a release point supplied by your script. It reports distance, closing speed, elapsed time, and estimated time to release in a fixed 1920x1080 design space.

Meter does not find colors, bars, or objects. Use Vision Tools, inference, or your own logic to determine:

  • the current point in frame pixels;
  • the release point in frame pixels; and
  • a bounding box around the measured element.

Meter and Vision continue to gain features while preserving published call signatures and data layouts. Use the SDK packaged with the installed Helios release for newly added calls.

Python Example

python
from helios import meter, vision


class CVWorker:
    def __init__(self, width, height):
        marker = vision.BgrRange((20, 120, 20), (140, 255, 140))
        self.finder = vision.ContourFinder(
            colors=[marker],
            roi=(300, 200, 1320, 680),
            width=(8, 160),
            height=(8, 160),
            max_results=2,
        )
        self.measurement = meter.Meter()

    def process(self, frame):
        results = self.finder.find()
        if len(results) < 2:
            return

        point = results[0].centroid
        release_point = results[1].centroid

        left = min(results[0].bounds[0], results[1].bounds[0])
        top = min(results[0].bounds[1], results[1].bounds[1])
        right = max(
            results[0].bounds[0] + results[0].bounds[2],
            results[1].bounds[0] + results[1].bounds[2],
        )
        bottom = max(
            results[0].bounds[1] + results[0].bounds[3],
            results[1].bounds[1] + results[1].bounds[3],
        )

        self.measurement.update(
            point=point,
            release_point=release_point,
            bounding_box=(left, top, right - left, bottom - top),
            padding=12,
        )

        distance = self.measurement.distance
        speed = self.measurement.speed
        eta = self.measurement.time_to_release

Call update(...) from process(frame). It uses the current frame's size and timestamp automatically and returns the same Meter object.

Update Call

python
measurement.update(
    point=(x, y),
    release_point=(release_x, release_y),
    bounding_box=(box_x, box_y, box_width, box_height),
    padding=0,
)

The two points and unpadded bounding box use current-frame pixels and must be inside the frame. Padding uses 1920x1080 design pixels and accepts:

  • one value for every side;
  • (horizontal, vertical); or
  • (left, top, right, bottom).

The padded box is clipped to the frame.

State

The latest update is available through these properties:

Property Meaning
point, release_point, bounding_box Supplied frame-pixel geometry and padded box
point_design, release_point_design Points mapped to 1920x1080 design coordinates
delta_design Release point minus current point
straight_distance Direct distance between the points
distance, previous_distance Current and previous configured-path distance
distance_delta New progress beyond the closest previously measured distance; zero without new progress
speed New progress divided by the time since the previous closest-distance sample; zero without new progress
delta_time Seconds over which new progress was measured; zero without new progress
elapsed_time Seconds since the timing baseline
time_to_release Estimated seconds at the current positive speed, otherwise -1.0
sample_count Number of samples since construction or reset
frame_sequence, timestamp_ns Current frame identifiers
path_algorithm, control_point_design Active path type and curve control point
meter_id Identifier for this Meter object

The first sample establishes timing, so its speed is zero. Repeated frames and backward movement also report zero speed and do not shorten the interval used for the next forward-progress sample. For distances 100, 90, 90, and 80 at 0, 10, 15, and 20 milliseconds, speeds are 0, 1000, 0, and 1000 design pixels per second. reset() clears measurements and timing while preserving the Meter object and its path/visual settings.

The constants meter.DESIGN_WIDTH and meter.DESIGN_HEIGHT are 1920 and 1080.

Straight and Curved Paths

Straight measurement is the default:

python
measurement.set_path(algorithm=meter.PATH_STRAIGHT)

Use a quadratic curve when the path being measured has a consistent bend:

python
measurement.set_path(
    algorithm=meter.PATH_QUADRATIC_BEZIER,
    curvature=0.25,
    segments=16,
)

curvature controls the side and amount of bend; zero produces straight geometry. segments accepts 2..64 and controls only how the curved path is drawn. Changing path settings resets the timing baseline. Current settings are available through path_settings.

Explicit Quadratic Path

When your detection supplies a curve control point, use:

python
measurement.update_quadratic(
    point=(100.5, 200.0),
    control_point=(160.0, 120.0),
    release_point=(220.0, 200.0),
    bounding_box=(100, 120, 121, 81),
    padding=0,
)

All three points use actual frame pixels and may be fractional. Call this during process(frame) with geometry valid for that frame. It measures the supplied quadratic curve for that update; use reset() when beginning a new tracked sequence. C++ provides updateQuadratic(point, controlPoint, releasePoint, bounds, padding).

Visuals

Visuals are enabled by default. They can draw the supplied box, path, distance, speed, time to release, and elapsed time:

python
measurement.set_visuals(
    enabled=True,
    show_bbox=True,
    show_path=True,
    show_distance=True,
    show_speed=True,
    show_time_to_release=True,
    show_elapsed_time=False,
)

Additional options set the box/path/metrics colors, box/path thickness, text scale, text gap, and Overlay target. Visual colors accept RGB or RGBA. Read the current values through visual_settings.

C++

CV C++ uses Helios::Meter::Meter from HeliosVisionSDK.hpp. In this integration fragment, the detect... and useMeasurement functions stand for your own detection and result-handling code:

cpp
Helios::Meter::Meter measurement;

void process(Helios::Frame& frame) {
    const Helios::Vision::PointI32 point = detectCurrentMarker(frame.image);
    const Helios::Vision::PointI32 releasePoint = detectReleaseMarker(frame.image);
    const Helios::Vision::RectI32 bounds = detectMeasurementBounds(frame.image);

    const Helios::Meter::State& state = measurement.update(
        point,
        releasePoint,
        bounds,
        {12, 12, 12, 12});

    useMeasurement(
        state.distance,
        state.speed,
        state.time_to_release_seconds);
}

Use setPath(...), pathSettings(), setVisuals(...), visualSettings(), state(), and reset() for the typed C++ equivalents. Returned state belongs to the Meter object and is overwritten by its next update or reset.

Public C declarations are in HeliosMeter.h. Use the packaged C++ wrapper and current SDK reference when adopting new calls.

Troubleshooting

  • Confirm both points and the unpadded bounding box are inside the current frame.
  • Call update(...) only from process(frame) so current dimensions and timing are available.
  • Expect zero speed on the first sample and after reset() or a path change.
  • Stationary or backward samples report zero speed and time_to_release == -1.0. Reset when beginning a new measurement sequence or changing the tracked target.
  • If measurements change with capture resolution, pass frame-pixel points and let Meter perform the design-space conversion.