A collection of small but useful tools for scientific publications and projects
Project description
vibing
A collection of small but useful tools for scientific publications and projects.
Modules
| Module | Description |
|---|---|
calibration |
Detect lens distortion using charuco boards |
sleap_convert |
Convert SLEAP predictions to ROI polygons |
geometry |
Pixel↔cm conversion, depth from boundaries |
pose |
Interpolate gaps, body hulls, velocity, distance, dwell time |
video |
FPS reader, frame counter, video info extraction |
Web Tools
| Tool | Description | Link |
|---|---|---|
| Pixel Scale Tool | Draw a line on your video, enter real distance, get px↔cm conversion | Launch |
Standalone Tools
These functions work independently for common tasks:
| Function | What it does | Example use case |
|---|---|---|
geometry.PixelScale |
Convert pixels ↔ real units (cm/mm) | "My ruler is 500px = 10cm, convert all measurements" |
geometry.depth_from_boundary |
How far a point is inside a region | "How deep is the snout in the arm?" |
pose.interpolate_gaps |
Fill short gaps in tracking data | "SLEAP lost tracking for 3 frames, fill it in" |
pose.body_hull |
Convex hull from body keypoints | "What's the body footprint polygon?" |
pose.body_hull_coverage |
% of body inside a region | "What fraction of the mouse is in zone A?" |
pose.track_velocity |
Speed from tracking data | "How fast is the mouse moving?" |
pose.track_distance |
Total distance traveled | "How far did the mouse walk?" |
pose.region_dwell_time |
Time spent in a region | "How long was the mouse in zone A?" |
video.get_video_info |
FPS, frames, dimensions, duration | "What's the frame rate of this video?" |
video.count_total_frames |
Batch frame counting | "How many frames across 500 videos?" |
calibration.check_video |
Measure lens distortion | "Does this GoPro video need undistortion?" |
Installation
From PyPI (recommended)
# Using uv
uv pip install vibing
# Using pip
pip install vibing
# With optional dependencies
uv pip install "vibing[calibration]" # Camera calibration tools (opencv)
uv pip install "vibing[sleap]" # SLEAP conversion tools
uv pip install "vibing[geometry]" # Geometry and pose tools (shapely)
uv pip install "vibing[all]" # Everything
Run CLI without installing (uvx)
# Run distortion checker directly
uvx --from "vibing[calibration]" vibing-distortion-check video.mp4
# Or install as a tool
uv tool install "vibing[calibration]"
vibing-distortion-check video.mp4
From GitHub
# Install from git
uv pip install "git+https://github.com/LeoMeow123/vibes.git[calibration]"
# Run without installing
uv tool run --from "git+https://github.com/LeoMeow123/vibes.git[calibration]" vibing-distortion-check video.mp4
From source
git clone https://github.com/LeoMeow123/vibes.git
cd vibes
uv pip install -e ".[all]"
Tools
Calibration (vibing.calibration)
Camera calibration and distortion analysis tools.
check_video- Analyze video for lens distortion using charuco boardcheck_image- Analyze single image for distortioncheck_batch- Batch process directory of videosCharucoBoardConfig- Configure charuco board parametersDistortionMetrics- Distortion analysis results
CLI: vibing-distortion-check
# Check single video
vibing-distortion-check video.mp4
# Batch process directory
vibing-distortion-check /path/to/videos --batch --output-csv results.csv
# Custom board configuration
vibing-distortion-check video.mp4 --squares-x 10 --squares-y 7
Undistortion (vibing.undistortion)
Video undistortion and perspective correction pipelines using OpenCV.
- spacecage-undistort - Fisheye lens distortion correction for NASA SpaceCage experiments with ROI-based calibration and SLEAP coordinate transformation
- tmaze-undistort - T-maze video processing with lens distortion removal and perspective transformation to top-down views using labeled ROIs and known physical dimensions
SLEAP Convert (vibing.sleap_convert)
Convert SLEAP predictions to ROI polygon YAML format.
slp_to_roi_yaml- Convert single SLP file to ROI YAMLconvert_batch- Batch convert directory of SLP filesextract_keypoints- Extract keypoints from SLP (low-level)ROITemplate- Define custom polygon templates for any arena
CLI: vibing-slp-to-yaml
# Convert single file
vibing-slp-to-yaml predictions.slp -o output.yml
# Batch convert directory
vibing-slp-to-yaml /path/to/slps --batch -o /path/to/yamls
# List available templates
vibing-slp-to-yaml --list-templates
Built-in templates: tmaze_horizontal (7-region T-maze with corner sharing)
Geometry (vibing.geometry)
Spatial analysis and unit conversion utilities.
Pixel-to-real conversion:
PixelScale- Convert between pixels and real units (cm, mm, etc.)px_to_real- Quick one-off conversioncompute_scale- Create scale from two reference points
Depth/distance:
depth_from_boundary- Calculate penetration depth into a regionsigned_distance- Signed distance to polygon (negative = inside)
from vibing.geometry import PixelScale, depth_from_boundary
from shapely.geometry import box
# Pixel to cm conversion: ruler is 500px = 10cm
scale = PixelScale.from_reference(pixels=500, real_distance=10, unit="cm")
print(scale.to_real(250)) # 5.0 cm
print(scale.to_real_area(2500)) # 1.0 cm²
# Or from two labeled points
scale = PixelScale.from_two_points((100, 100), (600, 100), real_distance=20, unit="cm")
# Depth from boundary
region = box(0, 0, 100, 100)
depth = depth_from_boundary((50, 50), region) # 50.0 (distance to nearest edge)
Pose (vibing.pose)
Tools for analyzing pose estimation data from SLEAP or similar trackers.
Region checking:
bodypart_in_region- Check if keypoint is inside polygonbodyparts_in_region- Batch check multiple keypointscheck_bodyparts_by_name- Check named body parts (e.g., "at least one hindpaw")count_bodyparts_in_region- Count keypoints inside region
Track interpolation:
interpolate_gaps- Fill short gaps in single keypoint trackinterpolate_track- Interpolate all keypoints in (T, J, 2) arraycount_gaps- Quality control: count and characterize gaps
Body hull:
body_hull- Convex hull from body keypoints (Polygon or vertices)body_hull_area- Calculate hull areabody_hull_centroid- Get hull center pointbody_hull_series- Compute hull for each frame in a trackbody_hull_coverage- Percentage of hull overlapping with ROI
Track analysis:
track_velocity- Instantaneous velocity (units/second)track_speed- Speed over time windowtrack_distance- Total distance traveledcumulative_distance- Cumulative distance at each frameregion_dwell_time- Time spent in a regionregion_dwell_frames- Boolean mask of frames inside regionmulti_region_dwell- Dwell time for multiple regions
from vibing.pose import track_velocity, track_distance, region_dwell_time
from shapely.geometry import box
import numpy as np
track = np.array([[0, 0], [3, 4], [6, 8], [9, 12]])
# Velocity in pixels/second
velocity = track_velocity(track, fps=30)
# Total distance traveled
dist = track_distance(track) # 15.0 pixels
# Time in a region
region = box(0, 0, 10, 10)
dwell = region_dwell_time(track, region, fps=30)
print(dwell['time_inside']) # seconds in region
Video (vibing.video)
Video metadata extraction with robust fallback methods.
get_video_info- Get comprehensive video metadata (FPS, frames, dimensions)read_fps- Robust FPS extraction with SLEAP/OpenCV fallbacksget_frame_count- Frame count from video or associated .slp fileget_duration- Video duration in secondscount_total_frames- Batch count frames across directoryscan_videos- Get VideoInfo for all videos in directory
from vibing.video import get_video_info, count_total_frames
# Single video info
info = get_video_info("experiment.mp4")
print(f"{info.fps} FPS, {info.frame_count} frames, {info.duration:.1f}s")
# Batch count (pre-flight check for large processing jobs)
total, n_videos = count_total_frames("/path/to/videos")
print(f"{total:,} frames across {n_videos} videos")
Quick Start
import numpy as np
from vibing.geometry import PixelScale
from vibing.pose import interpolate_gaps, body_hull
# Convert pixels to cm using a reference measurement
scale = PixelScale.from_reference(pixels=500, real_distance=10, unit="cm")
print(scale.to_real(250)) # 5.0 cm
# Fill short gaps in tracking data
track = np.array([[0, 0], [np.nan, np.nan], [2, 2], [3, 3]])
filled = interpolate_gaps(track, max_gap=7)
print(filled[1]) # [1., 1.] - gap interpolated
# Compute body footprint from keypoints
points = np.array([[0, 0], [10, 0], [10, 10], [0, 10]])
hull = body_hull(points)
print(hull.area) # 100.0
Development
# Clone and install in dev mode
git clone https://github.com/LeoMeow123/vibes.git
cd vibes
uv pip install -e ".[dev]"
# Run tests
pytest
# Run linter
ruff check src/
License
MIT License
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vibing-0.4.0.tar.gz.
File metadata
- Download URL: vibing-0.4.0.tar.gz
- Upload date:
- Size: 38.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93c730e622d491fdf9c047a567cc3f7b937edfba100d770814a2d7fdfa476452
|
|
| MD5 |
3de29ebd917dc7a5d7a026ea6d165909
|
|
| BLAKE2b-256 |
159bb8ca2fd604cfa28c4950d5f8ea57495278f0757a7fd780ca789cf7d17306
|
Provenance
The following attestation bundles were made for vibing-0.4.0.tar.gz:
Publisher:
publish.yml on LeoMeow123/vibes
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vibing-0.4.0.tar.gz -
Subject digest:
93c730e622d491fdf9c047a567cc3f7b937edfba100d770814a2d7fdfa476452 - Sigstore transparency entry: 811903544
- Sigstore integration time:
-
Permalink:
LeoMeow123/vibes@2f9c173b52893230a8d82cfa8ed054d2b19c8126 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/LeoMeow123
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2f9c173b52893230a8d82cfa8ed054d2b19c8126 -
Trigger Event:
push
-
Statement type:
File details
Details for the file vibing-0.4.0-py3-none-any.whl.
File metadata
- Download URL: vibing-0.4.0-py3-none-any.whl
- Upload date:
- Size: 41.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
610676b04752bac208f5cc477e7b4da680fc9edbcc4330a8705a9b11d35165bf
|
|
| MD5 |
3a55d3ac38ceb4c4136aff032d93c123
|
|
| BLAKE2b-256 |
82b322ee0d3fa5e2b13afd7b6dea8d13cf56157f7fa19b7d06a00d09a785623e
|
Provenance
The following attestation bundles were made for vibing-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on LeoMeow123/vibes
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vibing-0.4.0-py3-none-any.whl -
Subject digest:
610676b04752bac208f5cc477e7b4da680fc9edbcc4330a8705a9b11d35165bf - Sigstore transparency entry: 811903555
- Sigstore integration time:
-
Permalink:
LeoMeow123/vibes@2f9c173b52893230a8d82cfa8ed054d2b19c8126 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/LeoMeow123
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2f9c173b52893230a8d82cfa8ed054d2b19c8126 -
Trigger Event:
push
-
Statement type: