DataFlow-CV
🌊 Everything your model doesn't do. Analyse, convert, visualize, evaluate — a single CLI for all CV data.
A computer vision dataset processing library — analyse, convert, visualize, and evaluate annotations across YOLO, LabelMe, and COCO formats.
| 🔍 Analyse | Stats, train/val split, category filter, N-way partition & file sampling — format auto-detection | dataflow-cv analyse stats ... |
| 🔄 Convert | 6 directions: YOLO ↔ LabelMe ↔ COCO, plus model predictions | dataflow-cv convert yolo2coco ... |
| 🎨 Visualize | OpenCV rendering with color-coded classes, display & save modes | dataflow-cv visualize yolo ... |
| 📊 Evaluate | COCO mAP via pycocotools, single-threshold P/R/F1 per class | dataflow-cv evaluate detection ... |
| 💻 CLI + API | Click-based CLI with rich --help; Python API for pipelines |
from dataflow.convert import ... |
📦 Installation
pip install dataflow-cv # from PyPI
pip install pycocotools # optional: COCO RLE + evaluation
Or from source:
git clone https://github.com/zjykzj/DataFlow-CV.git
cd DataFlow-CV && pip install .
🚀 Quick Start
Command-line Interface
All required parameters (image directories, label directories, class files, output paths) are positional arguments for better usability. Use --help on any subcommand for detailed usage.
🔍 Dataset Analysis
# Dataset statistics (auto-detects YOLO / LabelMe / COCO)
dataflow-cv analyse stats yolo_labels/ --image-dir images/ --class-file classes.txt
dataflow-cv analyse stats labelme_json/
dataflow-cv analyse stats coco_annotations.json
# Train / test split (YOLO / LabelMe only — labels / images / both modes)
dataflow-cv analyse split -l yolo_labels/ outputs/ --ratio 0.8 --seed 42 -c classes.txt
dataflow-cv analyse split -i images/ outputs/ --ratio 0.8
dataflow-cv analyse split -l yolo_labels/ -i images/ outputs/ --ratio 0.8
# Category filter (keep a subset of categories, remap IDs per new classes.txt)
dataflow-cv analyse filter yolo_labels/ classes.txt classes_new.txt filtered/
dataflow-cv analyse filter coco_annotations.json classes.txt classes_new.txt filtered/
# N-way partition — YOLO / LabelMe only (labels drive, images follow by stem)
dataflow-cv analyse partition -n 4 --label-dir yolo_labels/ --image-dir images/ parts/
dataflow-cv analyse partition -n 4 --image-dir images/ --shuffle parts/
# File sampling — collect N files (random or sequential, labels / images / both modes)
dataflow-cv analyse sample -l yolo_labels/ output/ -n 10
dataflow-cv analyse sample -i images/ output/ -n 10 --no-shuffle
dataflow-cv analyse sample -l yolo_labels/ -i images/ output/ -n 5 --seed 42
# Sort by count descending (default: class ID ascending)
dataflow-cv analyse stats --sort-by count --descending yolo_labels/
# Verbose logging
dataflow-cv analyse stats --verbose yolo_labels/ --class-file classes.txt
🔄 Format Conversion
# YOLO → COCO
dataflow-cv convert yolo2coco images/ yolo_labels/ classes.txt output.json
# YOLO → COCO (with RLE encoding)
dataflow-cv convert yolo2coco images/ yolo_labels/ classes.txt output.json --do-rle
# YOLO → LabelMe
dataflow-cv convert yolo2labelme images/ yolo_labels/ classes.txt labelme_json/
# LabelMe → YOLO
dataflow-cv convert labelme2yolo labelme_json/ classes.txt yolo_labels/
# LabelMe → COCO
dataflow-cv convert labelme2coco labelme_json/ classes.txt output.json
# COCO → YOLO
dataflow-cv convert coco2yolo input.json yolo_labels/
# COCO → LabelMe
dataflow-cv convert coco2labelme input.json labelme_json/
# YOLO predictions → COCO (output: plain JSON list — prediction format)
dataflow-cv convert yolo2coco --prediction images/ yolo_preds/ classes.txt pred.json
# Options
dataflow-cv convert yolo2coco --verbose images/ labels/ classes.txt output.json
dataflow-cv convert yolo2coco --no-strict images/ labels/ classes.txt output.json
🎨 Visualization
# Visualize YOLO annotations
dataflow-cv visualize yolo images/ yolo_labels/ classes.txt --save visualized/
# Visualize LabelMe annotations
dataflow-cv visualize labelme images/ labelme_json/ --save visualized/
# Visualize COCO annotations
dataflow-cv visualize coco images/ coco_annotations.json --save visualized/
# Verbose logging + headless mode
dataflow-cv visualize yolo --verbose --no-display images/ yolo_labels/ classes.txt --save visualized/
📊 Evaluation
Evaluate object detection and instance segmentation models with COCO-standard metrics. Two COCO-format JSON files are required:
| File | Role | Format | How to create |
|---|---|---|---|
anno.json |
Ground Truth (GT) | Full COCO dict (images, annotations, categories) |
yolo2coco (label mode) |
pred.json |
Detection (DT) | Plain JSON list (with score) |
yolo2coco --prediction |
① Prepare Data
# GT: YOLO labels → COCO
dataflow-cv convert yolo2coco images/ yolo_labels/ classes.txt anno.json
# DT: YOLO predictions → COCO (add --prediction for model output)
dataflow-cv convert yolo2coco --prediction images/ yolo_preds/ classes.txt pred.json
⚠️
--predictionis required for YOLO prediction files — they have an extraconfidencetoken per line. The flag outputs a plain JSON list (not a full COCO dict), which is the standard DT format forloadRes(). Onlyyolo2cocosupports--prediction;labelme2cocodoes not need it (LabelMe has no label vs prediction distinction).
② Run Evaluation
# Object detection (bbox IoU)
dataflow-cv evaluate detection anno.json pred.json
dataflow-cv evaluate detection --verbose anno.json pred.json # per-class breakdown
dataflow-cv evaluate detection --prf1 anno.json pred.json # P/R/F1 only (skip mAP)
dataflow-cv evaluate detection --prf1 --prf1-iou 0.75 --prf1-method micro anno.json pred.json
# Instance segmentation (mask IoU)
dataflow-cv evaluate segmentation anno.json pred.json
dataflow-cv evaluate segmentation --verbose anno.json pred.json
# Save results as JSON
dataflow-cv evaluate detection --output results.json anno.json pred.json
# Custom log directory
dataflow-cv evaluate detection --verbose --log-dir logs/eval/ anno.json pred.json
③ Detection vs Segmentation
Two evaluation modes, distinguished by how overlap is measured:
- Object Detection — bounding box IoU. GT and DT require
bbox; DT additionally requiresscore. - Instance Segmentation — mask IoU. GT and DT require
bbox,segmentation(polygon or RLE), andarea; DT additionally requiresscore.
yolo2coco (label mode) and yolo2coco --prediction (prediction mode) automatically populate all required fields for both modes — no manual editing needed.
🐍 Python API
from dataflow.util.logging import LogConfig
from dataflow.analyse import StatsAnalyser, SplitAnalyser, FilterAnalyser, PartitionAnalyser, SampleAnalyser
from dataflow.convert import YoloAndCocoConverter
from dataflow.visualize import YOLOVisualizer
from dataflow.evaluate import DetectionEvaluator, compute_pr_f1
# ── Analyse ─────────────────────────────────────────
log_cfg = LogConfig(name="analyse", verbose=True)
# Dataset statistics
analyser = StatsAnalyser(log_config=log_cfg)
result = analyser.analyse("yolo_labels/", class_file="classes.txt")
print(f"{result.data.total_files} images, {result.data.total_annotations} objects")
# Train/test split (YOLO / LabelMe)
splitter = SplitAnalyser(log_config=log_cfg)
result = splitter.analyse(
output_dir="output/", ratio=0.8, seed=42,
label_dir="yolo_labels/", class_file="classes.txt",
)
print(f"Train: {result.data.train_count}, Val: {result.data.val_count}")
# Split with images (both mode — labels drive, images follow by stem)
result = splitter.analyse(
output_dir="output/", ratio=0.8, seed=42,
label_dir="yolo_labels/", image_dir="images/",
class_file="classes.txt",
)
# Category filter (keep / remap categories per new classes.txt)
filterer = FilterAnalyser(log_config=log_cfg)
result = filterer.analyse(
"yolo_labels/", original_class_file="classes.txt",
new_class_file="classes_new.txt", output_dir="filtered/",
)
# N-way partition (YOLO / LabelMe labels; images follow by stem)
partitioner = PartitionAnalyser(log_config=log_cfg)
result = partitioner.analyse(
output_dir="parts/", num=4,
label_dir="yolo_labels/", image_dir="images/",
)
# File sampling (labels, images, or both — random or sequential)
sampler = SampleAnalyser(log_config=log_cfg)
result = sampler.analyse(
output_dir="sampled/", count=10,
label_dir="yolo_labels/", shuffle=True, seed=42,
)
# ── Convert ──────────────────────────────────────────
# YOLO labels → COCO (label mode)
log_cfg = LogConfig(name="convert", verbose=True)
converter = YoloAndCocoConverter(source_to_target=True, log_config=log_cfg, strict_mode=True)
result = converter.convert(
source_path="yolo_labels/", target_path="anno.json",
class_file="classes.txt", image_dir="images/",
)
# YOLO predictions → COCO (prediction mode)
converter = YoloAndCocoConverter(source_to_target=True, prediction=True)
result = converter.convert(
source_path="yolo_preds/", target_path="pred.json",
class_file="classes.txt", image_dir="images/",
)
# ── Visualize ────────────────────────────────────────
visualizer = YOLOVisualizer(
label_dir="yolo_labels/", image_dir="images/",
class_file="classes.txt", is_show=True, is_save=True,
output_dir="visualized/", log_config=log_cfg,
)
result = visualizer.visualize()
# ── Evaluate ─────────────────────────────────────────
evaluator = DetectionEvaluator(log_config=LogConfig(name="eval", verbose=True))
result = evaluator.evaluate("anno.json", "pred.json")
print(f"AP: {result.metrics.ap:.3f}, AP50: {result.metrics.ap50:.3f}")
# Quick P/R/F1 at IoU=0.5 (default: macro averaging, bbox IoU)
prf1 = compute_pr_f1("anno.json", "pred.json", iou_threshold=0.5)
print(f"Macro F1: {prf1.overall.f1_score:.3f}")
# Micro averaging P/R/F1 (samples weighted equally)
prf1 = compute_pr_f1("anno.json", "pred.json", method="micro")
print(f"Micro F1: {prf1.overall.f1_score:.3f}")
# Segmentation P/R/F1 (mask IoU)
prf1 = compute_pr_f1("anno_segm.json", "pred_segm.json", iou_type="segm")
print(f"Segm F1: {prf1.overall.f1_score:.3f}")
📂 See the
samples/directory for complete examples:samples/analyse/(statistics & split),samples/convert/(6 conversion directions),samples/visualize/(YOLO, LabelMe, COCO),samples/evaluate/(detection & segmentation),samples/cli/(CLI workflows).
📖 Documentation
| Resource | Description |
|---|---|
| CLAUDE.md | Architecture overview, development guide, and known gotchas |
| CHANGELOG.md | Version history and breaking changes |
| specs/evaluate/ | Evaluation metric contracts — IoU, matching, AP/mAP/AR |
| specs/formats/ | External format contracts — YOLO, LabelMe, COCO, conversion rules |
| specs/modules/ | Internal module architecture, interface contracts, dependency constraints |
💡 Key Concepts
- Format-Native Coordinates: YOLO uses normalized [0,1] center-based coordinates; LabelMe and COCO use absolute pixel top-left. There is no hidden internal normalization — check
DatasetAnnotations.formatto interpret coordinate semantics. - Strict Mode (default): Validation errors raise exceptions immediately. Disable with
--no-strict(CLI) orstrict_mode=False(API) to skip invalid annotations and continue. - Verbose Logging:
--verboseenables per-module file logging viaLogManager— console shows INFO-level progress, log files capture DEBUG details. All logging is owned by modules; the CLI usesclick.echo()for terminal output. - Headless Support: Use
--no-displayfor servers/Docker — pair with--saveto render visualization images without a GUI window. - Keyboard Shortcuts (visualization):
q/ESCto exit,Enter/Spaceto advance, any other key to continue. - Evaluation:
--prf1computes P/R/F1 only (single-threshold, per-class TP/FP/FN) — skips the full COCOeval mAP pipeline for speed. Supports macro/micro averaging and bbox/mask IoU. Run without--prf1for standard COCO mAP. For both metrics, run twice. - Prediction Files: YOLO predictions use 6 tokens (detection) or even tokens (segmentation) vs 5/odd for labels. Use
--predictionwithyolo2coco— outputs a plain JSON list of annotation dicts compatible with pycocotoolsloadRes().
🔧 Development
For detailed developer guidance including advanced test commands, debugging, and architecture overview, see CLAUDE.md. The project also includes Claude Code skills for common tasks: /commit, /release, /dev, /spec, and /claude.
🧪 Testing
556 tests, 79% code coverage (5103 statements).
pytest # All tests
pytest --cov=dataflow --cov-report=term # With coverage
pytest tests/convert/test_yolo_and_coco.py # Single module
pytest tests/evaluate/test_evaluator.py # Single module
📊 Coverage by module
| Module | Coverage | Highlights |
|---|---|---|
dataflow/label/ |
72% | models (87%), base (83%), coco_handler (76%), labelme_handler (71%), yolo_handler (61%) |
dataflow/analyse/ |
79% | base (99%), utils (84%), stats (83%), filter (76%), partition (71%), split (63%) |
dataflow/convert/ |
85% | labelme_and_yolo (93%), yolo_and_coco (89%), utils (89%), coco_and_labelme (86%), base (80%), rle (80%) |
dataflow/visualize/ |
83% | yolo_vis (100%), labelme_vis (100%), coco_vis (93%), base (78%) |
dataflow/evaluate/ |
87% | evaluator (100%), result (99%), metrics (93%), base (91%), utils (67%) |
dataflow/cli/ |
75% | main (96%), visualize cmd (90%), utils (87%), evaluate cmd (83%), analyse cmd (64%), convert cmd (52%) |
dataflow/util/ |
100% | logging (100%) |
🎨 Code Quality
pip install -e .[dev] # Install dev dependencies
black dataflow tests samples # Format
isort dataflow tests samples # Sort imports
mypy dataflow # Type check
flake8 dataflow tests samples # Lint
🔗 Pre-commit Hooks (Optional)
pip install pre-commit
pre-commit install # Install git hooks (run once)
# After this, every `git commit` auto-runs:
# black → isort → flake8 → whitespace checks
pre-commit run --all-files # Manual run against all files
📁 Project Structure
dataflow/
├── label/ # Annotation handlers + data models
├── analyse/ # Dataset stats, train/val split, category filter, N-way partition, file sampling
├── convert/ # Format converters, RLE utility, log templates
├── visualize/ # OpenCV-based rendering, log templates
├── evaluate/ # pycocotools-based metrics, log templates
├── util/ # Unified logging (LogManager + format helpers)
└── cli/ # CLI entry point, commands, validation
tests/ # Unit & integration tests (556 tests, conftest fixtures)
samples/ # Python API usage examples (analyse, convert, visualize, evaluate, cli)
assets/ # Test data (det/seg by format)
specs/ # Canonical specifications (evaluate/ + formats/ + modules/)
🤝 Contributing
Contributions are welcome! Please review CLAUDE.md for architecture and development patterns before contributing.
- 🍴 Fork the repository
- 🌿 Create a feature branch
- ✏️ Make your changes — spec-first: if a change affects a contract in specs/, update the spec before the code (SDD, see the
/specskill) - 🧪 Add or update tests as needed
- ✅ Ensure code passes formatting and linting checks
- 📬 Submit a pull request
📄 License
This project is licensed under the MIT License — see LICENSE for details.
🙏 Acknowledgments
- Thanks to the creators of YOLO, LabelMe, and COCO formats for establishing these annotation standards
- Built with OpenCV, NumPy, Click, and pycocotools
- Inspired by the need for seamless format conversion in multi-tool CV pipelines
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 dataflow_cv-1.9.0.tar.gz.
File metadata
- Download URL: dataflow_cv-1.9.0.tar.gz
- Upload date:
- Size: 113.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f50451d5a40984c80b3ab36dbdb6173a37ae5a9dc4572bb80ff4eab50777ce3
|
|
| MD5 |
58cf82f346eff94b7a1a197e8a9a76e4
|
|
| BLAKE2b-256 |
935ea9f3eb735bf44e74a0f1a7e48a42289bb0303aa61ef97999a7a4b48d079f
|
Provenance
The following attestation bundles were made for dataflow_cv-1.9.0.tar.gz:
Publisher:
python-publish.yml on zjykzj/DataFlow-CV
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dataflow_cv-1.9.0.tar.gz -
Subject digest:
9f50451d5a40984c80b3ab36dbdb6173a37ae5a9dc4572bb80ff4eab50777ce3 - Sigstore transparency entry: 2234104026
- Sigstore integration time:
-
Permalink:
zjykzj/DataFlow-CV@e99e8a05cbc84b38a686eea743e01db5edc43657 -
Branch / Tag:
refs/tags/v1.9.0 - Owner: https://github.com/zjykzj
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@e99e8a05cbc84b38a686eea743e01db5edc43657 -
Trigger Event:
release
-
Statement type:
File details
Details for the file dataflow_cv-1.9.0-py3-none-any.whl.
File metadata
- Download URL: dataflow_cv-1.9.0-py3-none-any.whl
- Upload date:
- Size: 137.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd2b2b6b504b0c4fc27aec75b02e8d652b0a676263d9d16321b712b3d278e4c5
|
|
| MD5 |
5e81d15729f60b8fd73f153bfb98174f
|
|
| BLAKE2b-256 |
7792fa0e4781db9df86290ec210602bda36c9192137045622688eec3be18f57f
|
Provenance
The following attestation bundles were made for dataflow_cv-1.9.0-py3-none-any.whl:
Publisher:
python-publish.yml on zjykzj/DataFlow-CV
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dataflow_cv-1.9.0-py3-none-any.whl -
Subject digest:
cd2b2b6b504b0c4fc27aec75b02e8d652b0a676263d9d16321b712b3d278e4c5 - Sigstore transparency entry: 2234104702
- Sigstore integration time:
-
Permalink:
zjykzj/DataFlow-CV@e99e8a05cbc84b38a686eea743e01db5edc43657 -
Branch / Tag:
refs/tags/v1.9.0 - Owner: https://github.com/zjykzj
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@e99e8a05cbc84b38a686eea743e01db5edc43657 -
Trigger Event:
release
-
Statement type: