Anchor-based keypoint tracking through CoTracker3, as a napari plugin.
Project description
napari-cotrack
A napari plugin for anchor-based keypoint tracking through CoTracker3. Label a few frames in napari; CoTracker3 propagates those keypoints across the rest of the video; iterate by fixing wrong predictions and re-running.
Install
The recommended path on every platform is the one-shot bootstrap script. It
installs uv if you don't already have it, then
uv tool install napari-cotrack — putting napari-cotrack on your PATH and
fetching the ~1.5 GB of Python deps (torch, napari, cv2, …) on first run.
macOS / Linux:
curl -LsSf https://raw.githubusercontent.com/RaulSimpetru/napari-cotrack/main/scripts/install.sh | bash
Windows (PowerShell):
irm https://raw.githubusercontent.com/RaulSimpetru/napari-cotrack/main/scripts/install.ps1 | iex
Then run napari-cotrack. To upgrade later: uv tool upgrade napari-cotrack.
Already have uv?
uv tool install napari-cotrack
napari-cotrack
Working in a clone of the repo?
uv sync
uv run napari-cotrack
Optional: install ffmpeg for the fast extract-all path
Stage 4's "Extract all frames" runs in a single ffmpeg pass (~10–50× faster on
H.264 sources) when ffmpeg is on PATH, otherwise falls back to a per-frame
imageio loop.
| OS | Install ffmpeg |
|---|---|
| macOS | brew install ffmpeg |
| Ubuntu / Debian | sudo apt install ffmpeg |
| Windows | winget install ffmpeg (or download from gyan.dev) |
Tested platforms
- macOS arm64 (Apple Silicon) — primary development target, end-to-end tested on a real 1500-frame project.
- Linux x86_64 and Windows x86_64 — code is portable (PyQt6 + pathlib + ffmpeg subprocess + napari thread_worker), all deps publish wheels for these platforms, but I haven't run the GUI on them. Open an issue if anything breaks — should be a small fix.
The five-stage loop
The dock widget mirrors the loop:
- Extract anchor frames — every Nth frame, or top K most diverse via k-means on RGB histograms.
- Label keypoints — load anchors into the viewer and click them in.
One Points layer named
labels, colour driven by abodypartproperty. Click moves an existing point at the same(frame, bodypart)instead of duplicating, then auto-advances to the next bodypart. - Track with CoTracker3 — propagates labels (anchors + every
corrections/round_*folder) across the whole video. Runs in a naparithread_worker, log streams into the dock pane. - Review and fix — extract every video frame as PNG (ffmpeg fast path
if available), load them into napari, fix wrong predictions, Promote
to write only the changed rows into a new
corrections/round_NNN/. Or detect scene-confusion jumps and extract a representative frame per bad range. - Render and inspect — Hampel + 1€ filter, then the cv2 overlay
renderer with bodypart trails.
Play with ffplayon the result.
Re-running stage 3 after a correction round folds those new labels in automatically.
On-disk format
A project is a directory ending in .naparitracker/:
<name>.naparitracker/
project.toml # video path, bodyparts, per-stage knobs
anchors/
img0023.png ...
labels.csv # long-form: frame,bodypart,x,y,vis
corrections/
round_001/labels.csv
round_002/labels.csv
tracks.csv # dense: every (frame, bodypart)
tracks_filtered.csv
overlay.mp4
review/
img0000.png ...
labels.csv # prefilled from tracks.csv
baseline.csv # snapshot for diff-promote
project.toml is hand-editable TOML. Every stage's knobs version with the
project, so git diff on project.toml shows what changed.
Headless CLIs
Every stage is also a module CLI for batch / scripted use:
uv run python -m napari_cotrack.pipeline.extract anchors \
--video VIDEO --output PROJECT/anchors \
--bodyparts thumb,index,middle,ring,wrist \
--mode diverse --n 30
uv run python -m napari_cotrack.pipeline.track --project PROJECT
uv run python -m napari_cotrack.pipeline.filter --project PROJECT
uv run python -m napari_cotrack.pipeline.render --project PROJECT
uv run python -m napari_cotrack.pipeline.review extract-all --project PROJECT --force
uv run python -m napari_cotrack.pipeline.review promote --project PROJECT
uv run python -m napari_cotrack.pipeline.review jumps --project PROJECT [--extract-corrections]
All accept --verbose for per-chunk / per-bodypart detail.
Tests
uv run python -m pytest tests/
Covers extract uniform/diverse, label-CSV union semantics, sparse-frame
mapping, CSV round-trip. Stage 3 (track) needs a real GPU + checkpoint;
smoke against the synthetic fixture in tests/_make_fixture.py.
Keyboard
While editing in napari:
- N / Shift+N — next / previous bodypart (avoids napari's default Tab/Up/Down)
- Ctrl+S / Cmd+S — save labels.csv
- Right / Left — next / prev frame (napari default)
- Delete — remove selected points (napari default)
Save also fires automatically when you close napari, as a safety net.
Project details
Release history Release notifications | RSS feed
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 napari_cotrack-0.1.7.tar.gz.
File metadata
- Download URL: napari_cotrack-0.1.7.tar.gz
- Upload date:
- Size: 226.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97053647696332f5d0f6d02308610c30b5a193e956961dcb0ea43f026a6cbd55
|
|
| MD5 |
9605525ede331f9074626640fb79bb5c
|
|
| BLAKE2b-256 |
6f577cc2ab6cbc4057097e62b37cd651e5c42e58ce969feeb733766c2f3c6e89
|
Provenance
The following attestation bundles were made for napari_cotrack-0.1.7.tar.gz:
Publisher:
publish.yml on RaulSimpetru/napari-cotrack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
napari_cotrack-0.1.7.tar.gz -
Subject digest:
97053647696332f5d0f6d02308610c30b5a193e956961dcb0ea43f026a6cbd55 - Sigstore transparency entry: 1421522027
- Sigstore integration time:
-
Permalink:
RaulSimpetru/napari-cotrack@a3277720e54c0b8465c8890cc0433e33f7696b69 -
Branch / Tag:
refs/tags/v0.1.7 - Owner: https://github.com/RaulSimpetru
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a3277720e54c0b8465c8890cc0433e33f7696b69 -
Trigger Event:
push
-
Statement type:
File details
Details for the file napari_cotrack-0.1.7-py3-none-any.whl.
File metadata
- Download URL: napari_cotrack-0.1.7-py3-none-any.whl
- Upload date:
- Size: 103.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53131bf2a0dde624a98ce57752c5c1303d478dd03c8bc8d5eb54d72c99c9aa2f
|
|
| MD5 |
4c226a84cc872c97521e9e2cce8771f9
|
|
| BLAKE2b-256 |
f9b2a035275a78989081c4b5265b55dae240a3b4dd8335aa5c36bd7bdccd9a62
|
Provenance
The following attestation bundles were made for napari_cotrack-0.1.7-py3-none-any.whl:
Publisher:
publish.yml on RaulSimpetru/napari-cotrack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
napari_cotrack-0.1.7-py3-none-any.whl -
Subject digest:
53131bf2a0dde624a98ce57752c5c1303d478dd03c8bc8d5eb54d72c99c9aa2f - Sigstore transparency entry: 1421522201
- Sigstore integration time:
-
Permalink:
RaulSimpetru/napari-cotrack@a3277720e54c0b8465c8890cc0433e33f7696b69 -
Branch / Tag:
refs/tags/v0.1.7 - Owner: https://github.com/RaulSimpetru
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a3277720e54c0b8465c8890cc0433e33f7696b69 -
Trigger Event:
push
-
Statement type: