Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

visioncore

Camera-based dimensional measurement on live video streams. A small, dependency-light Python library built around four composable layers — calibration, detection, geometry, measurement — plus a thin streaming loop on top.

What it does

  • Calibrate a uniform pixel-to-millimeter scale from a known reference (credit card, ruler, ArUco marker pair) and, optionally, full camera intrinsics from chessboard images.
  • Detect objects with classical contour analysis out of the box, or plug in any callable matching the Detector protocol (YOLO, SAM, MediaPipe…).
  • Measure distances, polyline lengths, polygon and mask areas, mask perimeters, and full object dimensions (width × height × area × perimeter) in real-world units.
  • Stream the whole pipeline against a webcam or video file with a tiny context-managed CameraStream and a Pipeline of frame processors.

Install

pip install -e .[dev]

Runtime dependencies are just NumPy and OpenCV — no deep-learning frameworks.

Quick start

Aimed at measuring household objects — remotes, spoons, pans, packaging — using a coin of known diameter as the calibration reference. A US quarter is exactly 24.26 mm across; common alternatives are listed in examples/live_measure.py.

import cv2
import visioncore as vc

# 1. Calibrate against a coin laid flat in the same plane as the object.
#    (US quarter diameter = 24.26 mm.)
frame = cv2.imread("coin_and_remote.jpg")
# ...let the user click both edges across the coin; here we hard-code:
scale = vc.calibrate_scale_from_reference(
    p1=(412, 388), p2=(580, 392),
    known_distance_mm=24.26,
    label="us-quarter",
)

# 2. Detect parts in the same scene.
detector = vc.ContourDetector(min_area_px=2000, invert=True)
detections = detector.detect(frame)

# 3. Measure each detection in millimeters.
for det in detections:
    dims = vc.measure_object_dimensions(det, scale)
    print(dims["width"], dims["height"], dims["area"])

The runnable demo at examples/live_measure.py does the same thing live: press c, click both edges of the coin, press c again, and the live feed annotates every detected object with {w} x {h} mm.

Design notes

  • Pixel space and world space are strictly separated. geometry.py consumes pixels and returns pixels. measure.py is the only module that imports ScaleCalibration and emits world units. Keeping that boundary clean makes it easy to swap calibration strategies later (per-pixel scale fields, perspective rectification, full 3D back-projection) without rewriting geometry.
  • Detectors and pose estimators are typing.Protocols, not base classes. Anything with a detect(image) -> list[Detection] method is a Detector. No inheritance required — bring your own model.
  • Tiny dependency surface. NumPy and OpenCV only at runtime. Heavier ML stacks plug in behind the protocols.
  • Public API only via visioncore/__init__.py. Treat module paths as internal implementation detail.

Limitations and accuracy

A uniform pixel-to-mm scale is a useful first approximation, but it assumes:

  • Lens distortion is negligible. For wide-angle or fisheye lenses, run calibrate_intrinsics(...) against a chessboard, attach the resulting IntrinsicCalibration to your ScaleCalibration (or use UndistortProcessor in your pipeline) before measuring.
  • The object lies in the same plane as the calibration reference. Out-of-plane height effectively magnifies an object — even a few millimeters of standoff can change the apparent size by several percent.
  • The camera optical axis is roughly perpendicular to that plane. Perspective skew is not corrected here. For oblique views you need a homography-based rectification step (planned, not in v0.1).
  • The reference is measured precisely. Click error of one pixel on a 500 px reference translates directly to a 0.2 % scale error.

In practice, expect ~1–3 % accuracy on flat objects under decent lighting with a static camera. Re-calibrate whenever the camera or scene geometry moves.

Layout

visioncore/
├── __about__.py          # __version__
├── __init__.py           # public re-exports
├── types.py              # Point, Box, Mask, Pose, Detection, Frame
├── calibration.py        # IntrinsicCalibration, ScaleCalibration, helpers
├── detection.py          # Detector protocol, ContourDetector
├── pose.py               # PoseEstimator protocol, ManualPose, CallablePoseEstimator
├── geometry.py           # pixel-space primitives
├── measure.py            # the only place pixels become millimeters
└── stream.py             # CameraStream, Pipeline, run()

tests/test_visioncore.py  # synthetic-image test suite
examples/live_measure.py  # webcam demo

License

Apache 2.0 — see LICENSE.

About

A Python library for measurement, observation, and calibrated judgment from camera images — the perception layer for human-helper AI applications.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages