Metadata-Version: 2.4
Name: magiclabel
Version: 0.3.0
Summary: AI-assisted image annotation CLI for computer vision datasets
Author: Rohan Rustagi
License: MIT
Keywords: annotation,labeling,computer-vision,yolo,dataset,object-detection
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: ultralytics>=8.0.0
Requires-Dist: typer>=0.9.0
Requires-Dist: rich
Requires-Dist: opencv-python
Requires-Dist: gradio
Requires-Dist: gradio_image_annotation
Requires-Dist: torch
Requires-Dist: torchvision
Dynamic: license-file

# MagicLabel

> AI‑assisted image labeling CLI — go from raw images to your own trained model, end to end.

Good models start with good data, and labeling that data by hand is the slowest part of any computer‑vision project. **MagicLabel** runs the whole loop from one command line:

1. **Auto‑detect** objects in a folder of images — including custom objects you describe in plain words (no training needed).
2. **Review & fix** the labels in a browser — draw, move, resize, relabel, delete.
3. **Train** a custom YOLO model on your labeled data.
4. **Reuse** your named model (`uav.pt`, `rohan.pt`, …) to auto‑label the next batch — the loop closes.

Everything runs **locally and free** — no account, no cloud upload, no Docker. Works in **Google Colab** too (`--share`).

![Python](https://img.shields.io/badge/python-3.8%2B-blue)
![License](https://img.shields.io/badge/license-MIT-green)
![PyPI](https://img.shields.io/pypi/v/magiclabel)

---

## Features

- 🔍 **Auto‑detect** — label an image folder with a YOLO model (the 80 COCO classes out of the box).
- 🗣️ **Open‑vocabulary detect** — `--prompt "drone,missile"` detects *anything you name*, with no training (YOLO‑World).
- 🖊️ **Visual review** — a browser UI to draw / move / resize / relabel / delete boxes. Type **any custom class name** you want.
- 🎓 **Train** — fine‑tune a custom model (YOLO26 by default) on your labeled data and save it as a named `.pt`.
- 🎬 **Predict** — test any model on an image, video, or folder; annotated results saved automatically.
- 🔄 **Export** — convert YOLO labels to COCO JSON.
- 🏷️ **Inspect** — print the class names a model knows.
- ☁️ **Colab‑ready** — `--share` gives you a public link to the review UI from any remote machine.

---

## Installation

```bash
pip install magiclabel
```

> **Heads‑up:** MagicLabel depends on `torch` and `ultralytics`, so installation pulls ~1 GB of packages. That's normal for a computer‑vision tool.

From source:

```bash
git clone https://github.com/your-username/magiclabel.git
cd magiclabel
python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e .
```

Verify:

```bash
magiclabel --help
```

---

## Quick start — the full loop

```bash
# 1. Auto-label a folder of images (80 COCO classes)
magiclabel detect ./images --output ./labels

#    …or detect a CUSTOM object by describing it (no training):
magiclabel detect ./images --prompt "drone, quadcopter" --output ./labels

# 2. Review and fix the labels in your browser
magiclabel review ./images ./labels

# 3. Train your own model on the corrected dataset
magiclabel train ./images ./labels --name uav.pt --epochs 100

# 4. Test it — run it on an image, folder, or video and eyeball the results
magiclabel predict ./drone-video.mp4 --model uav.pt

# 5. Reuse your model to auto-label the next batch — the loop closes
magiclabel detect ./new_images --model uav.pt --output ./labels2
```

---

## Command reference

Run `magiclabel <command> --help` at any time for the full option list.

### `detect` — auto‑annotate images with bounding boxes

Runs a model over every image in a directory. Writes one YOLO‑format `.txt` per image **plus a `classes.txt`** (the class list, one name per line, id = line number). `classes.txt` is **merged, never overwritten** — re‑running `detect` or adding custom classes in `review` keeps ids consistent, and only classes that are actually detected get an id.

```bash
magiclabel detect SOURCE [OPTIONS]
```

| Option     | Default                           | Description                                                                                                    |
| ---------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `SOURCE`   | *(required)*                      | Directory of images (`.jpg`, `.jpeg`, `.png`, `.bmp`, `.tif`, `.tiff`)                                          |
| `--prompt` | *(none)*                          | Comma‑separated object names for **open‑vocabulary** detection, e.g. `"drone,missile"`. No training needed.      |
| `--model`  | `yolo26n.pt` / `yolov8s-world.pt` | Model file. Defaults to `yolo26n.pt` (closed‑set) or `yolov8s-world.pt` when `--prompt` is given. Pass your own trained `.pt` to use it. |
| `--output` | `./labels_detect`                 | Output directory for label files + `classes.txt`                                                                |
| `--conf`   | `0.25`                            | Confidence threshold (0–1); higher = fewer, surer boxes                                                          |

**Examples**

```bash
# Closed-set: detect the 80 COCO classes
magiclabel detect ./images --output ./labels --conf 0.3

# Open-vocabulary: detect objects YOLO was never trained on
magiclabel detect ./images --prompt "drone, fixed-wing aircraft" --conf 0.1 --output ./labels

# Use a bigger pretrained model for better accuracy
magiclabel detect ./images --model yolov8x.pt --output ./labels

# Use YOUR OWN trained model (see `train` below)
magiclabel detect ./new_images --model uav.pt --output ./predictions --conf 0.25
```

> **Tip:** open‑vocabulary detection is great on common/clear objects and hit‑or‑miss on unusual ones. For hard objects, hand‑label a batch in `review`, `train` a model, then `detect --model your.pt` to auto‑label the rest.

---

### `review` — draw, fix, and label boxes in your browser

Launches a local web app (default <http://127.0.0.1:7860>) to inspect and correct labels.

```bash
magiclabel review IMAGES_DIR LABELS_DIR [OPTIONS]
```

| Argument / Option      | Default        | Description                                                                                         |
| ---------------------- | -------------- | --------------------------------------------------------------------------------------------------- |
| `IMAGES_DIR`           | *(required)*   | Directory of images                                                                                  |
| `LABELS_DIR`           | *(required)*   | Directory of YOLO `.txt` labels (and `classes.txt`)                                                  |
| `--model`              | `yolo26n.pt`   | Model whose class names label the boxes. Use **`--model none`** to start a clean custom dataset with no preset names. |
| `--share / --no-share` | auto           | Create a public `*.gradio.live` link. **Auto‑enabled on Google Colab**; use `--share` on any other remote machine. |

**Examples**

```bash
# Review labels locally
magiclabel review ./images ./labels

# Start a CLEAN custom dataset (first class you type gets id 0 — no COCO baggage)
magiclabel review ./images ./my_labels --model none

# On Google Colab / a remote VM — get a public link
magiclabel review ./images ./labels --share
```

**In the UI you can:**

- **Draw** a new box — click and drag on the image.
- **Move / resize** — click a box and drag it or its corner handles.
- **Set the class** — double‑click a box, **type any class name** (`drone`, `crack`, `logo`), then click the editor's apply/✓ to commit. New names are appended to `classes.txt` automatically.
- **Delete** — the box's remove button, the <kbd>Delete</kbd> key, or **Clear All Boxes**.
- **Switch images** — the dropdown at the top (opens on the first image that already has boxes).
- **Save Changes** — writes boxes back to the `.txt`; the view reloads from disk so you can confirm exactly what was saved.

> Edits live only in the browser until you click **Save Changes**. Saving an image with no boxes writes an empty label file (a valid "no objects" annotation).

---

### `train` — train your own custom model

Fine‑tunes a YOLO model on your labeled dataset and saves it under any name you choose. This is **transfer learning**: the base model provides general visual knowledge; your data teaches it *your* classes. The output `.pt` contains **only your classes**.

The dataset is automatically **compacted**: only class ids that actually appear in your labels are trained, remapped to a contiguous `0..K‑1` and named from `classes.txt`. Stray or out‑of‑range ids can't crash training.

```bash
magiclabel train IMAGES_DIR LABELS_DIR [OPTIONS]
```

| Option        | Default      | Description                                              |
| ------------- | ------------ | -------------------------------------------------------- |
| `IMAGES_DIR`  | *(required)* | Directory of images                                      |
| `LABELS_DIR`  | *(required)* | Directory of YOLO labels + `classes.txt`                 |
| `--name`      | `custom.pt`  | Output model name, e.g. `uav.pt`, `rohan.pt`             |
| `--base`      | `yolo26n.pt` | Base model to fine‑tune (or your own `.pt` to keep improving it) |
| `--epochs`    | `50`         | Training epochs                                          |
| `--imgsz`     | `640`        | Training image size                                      |
| `--val-split` | `0.2`        | Fraction of images held out for validation               |

**Examples**

```bash
# Train a drone detector
magiclabel train ./images ./labels --name uav.pt --epochs 100

# Bigger base model = more accurate (needs more data/compute)
magiclabel train ./images ./labels --name uav.pt --base yolo26s.pt --epochs 100

# Continue improving YOUR model with new data
magiclabel train ./more_images ./more_labels --name uav2.pt --base uav.pt
```

Output: your named `.pt` in the current directory, plus a `<name>_dataset/` folder containing the train/val split and `data.yaml`.

**Then test it:**

```bash
magiclabel predict ./test_images --model uav.pt       # annotated images saved for you
```

> A useful model needs **dozens‑to‑hundreds of labeled images** and enough epochs. Training is much faster on a GPU (CUDA/Apple‑Silicon used automatically). Test on images the model has never seen.

---

### `predict` — test a model on images or video

Runs inference on an image, a **video**, or a folder of images and saves the **annotated results** (boxes drawn on) automatically. This is the one‑liner version of the usual "load the model, call `.predict(source, save=True)`" Python snippet.

```bash
magiclabel predict SOURCE [OPTIONS]
```

| Option     | Default          | Description                                        |
| ---------- | ---------------- | -------------------------------------------------- |
| `SOURCE`   | *(required)*     | An image, a video (`.mp4`, `.avi`, …), or a directory of images |
| `--model`  | `yolo26n.pt`     | Model to run — e.g. your trained `uav.pt`          |
| `--conf`   | `0.25`           | Confidence threshold                               |
| `--output` | `./predictions`  | Directory for annotated results (saved in `run/`)  |

**Examples**

```bash
# Test your drone model on a video — saves an annotated video
magiclabel predict ./drone-comp.mp4 --model uav.pt

# Test on a folder of new images
magiclabel predict ./test_images --model uav.pt --conf 0.25

# Weak model finding nothing? Lower the threshold to see what it's unsure about
magiclabel predict ./test_images --model uav.pt --conf 0.1
```

Output: annotated copies of your input in `./predictions/run/`, plus a summary (`✓ 87 detections over 240 frame(s)/image(s)`).

> `predict` draws boxes on media for **eyeballing results**; `detect` writes YOLO label files for **building datasets**. Use `predict` to judge your model, `detect` to label with it.

---

### `yolo2coco` — export labels to COCO JSON

Converts a YOLO detection dataset into a single COCO‑format JSON (for Detectron2, MMDetection, etc.).

```bash
magiclabel yolo2coco IMAGES_DIR LABELS_DIR OUTPUT_JSON --class NAME [--class NAME ...]
```

| Argument / Option | Description                                               |
| ----------------- | --------------------------------------------------------- |
| `IMAGES_DIR`      | Directory of images                                       |
| `LABELS_DIR`      | Directory of YOLO detection labels                        |
| `OUTPUT_JSON`     | Path to write the COCO JSON file                          |
| `--class`         | Class names **in class‑id order** (0, 1, 2, …), repeated  |

**Example**

```bash
magiclabel yolo2coco ./images ./labels annotations.json --class drone
# ✓ COCO JSON saved to annotations.json (1359 images, 696 annotations, 1 categories)
```

Any class id found in the labels without a `--class` name is auto‑named `class_<id>` (with a warning), so the export always succeeds.

---

### `export-classes` — list a model's class names

```bash
magiclabel export-classes [MODEL]
```

**Examples**

```bash
magiclabel export-classes yolo26n.pt
# 0: person
# 1: bicycle
# ...

magiclabel export-classes uav.pt
# 0: drone     ← proof your trained model contains only YOUR classes
```

---

## Using MagicLabel in Google Colab

```python
# Cell 1 — install
!pip install magiclabel

# Cell 2 — mount Drive so your work survives the session
from google.colab import drive
drive.mount('/content/drive')

# Cell 3 — auto-label
!magiclabel detect /content/drive/MyDrive/data/images --output /content/drive/MyDrive/data/labels

# Cell 4 — review with a public link (auto-enabled on Colab; --share to be explicit)
!magiclabel review /content/drive/MyDrive/data/images /content/drive/MyDrive/data/labels --share
# → click the printed https://xxxx.gradio.live link

# Cell 5 — train (Runtime → Change runtime type → T4 GPU for speed)
!magiclabel train /content/drive/MyDrive/data/images /content/drive/MyDrive/data/labels \
    --name uav.pt --epochs 100

# Cell 6 — test the model on a video or new images (annotated output saved)
!magiclabel predict /content/drive/MyDrive/data/drone-comp.mp4 --model uav.pt \
    --output /content/drive/MyDrive/data/predictions
```

- Use the **`gradio.live` URL**, not `127.0.0.1` — local addresses point at the Colab VM.
- The `review` cell stays "running" while the server is live; stop the cell to shut it down.
- **Save to Drive** — Colab wipes the VM when the session ends.
- The share link tunnels through Gradio's servers; for sensitive images, review locally instead.

---

## Label format

MagicLabel reads and writes the **YOLO detection** format: one `.txt` per image, sharing the image's base name (`drone1.jpg` → `drone1.txt`). Each line is one box:

```text
<class_id> <x_center> <y_center> <width> <height>
```

All coordinates are **normalized to 0–1**. Example:

```text
0 0.501818 0.467213 0.669091 0.573770
```

A `classes.txt` alongside the labels maps ids to names (id = line number):

```text
drone
```

Images without a `.txt` (or with an empty one) are valid — they count as background/negative samples during training.

---

## Tips & troubleshooting

- **Model downloads:** the first run of a new model downloads its weights into the current directory and reuses them after.
- **No boxes from your trained model?** Lower the threshold: `--conf 0.1` (or `0.05`) to surface weak predictions.
- **Speed:** detection is fine on CPU; training really wants a GPU (used automatically when present).
- **"No images found":** the source must be a directory of images with a supported extension.
- **Port 7860 already in use:** an old review server is still running:
  ```bash
  kill $(lsof -nP -tiTCP:7860 -sTCP:LISTEN)
  ```
- **Review doesn't hot-reload** — stop it (<kbd>Ctrl</kbd>+<kbd>C</kbd>) and relaunch after changing files on disk.

---

## Changelog

### 0.3.0
- New `predict` command — test a model on an image, **video**, or folder; annotated results saved automatically.
- **YOLO26 by default** — `detect`, `train --base`, `review --model`, and `export-classes` now default to `yolo26n.pt` (newer generation than YOLOv8).
- Documentation overhaul: full command reference with examples, Google Colab guide.

### 0.2.1
- **Fixed:** `detect` no longer overwrites `classes.txt` — the class list is merged and kept compact (only detected classes get ids), so custom classes added in `review` stay consistent.
- **Fixed:** `train` now compacts the dataset to the classes actually used, remapping ids to `0..K‑1` — out‑of‑range label ids can no longer crash training ("Label class N exceeds dataset class count").

### 0.2.0
- New `train` command — fine‑tune a named custom `.pt` on your labeled dataset.
- Open‑vocabulary detection: `detect --prompt "anything,you,name"` (YOLO‑World).
- `review`: free‑text custom class names with a persistent `classes.txt` registry; `--share` for Colab/remote use (auto‑detected on Colab); class names shown instead of raw ids; per‑box delete, Clear All, and save‑then‑reload verification.
- Rewritten `yolo2coco` (correct YOLO→COCO conversion, auto‑named missing classes).

### 0.1.0
- Initial release: `detect`, `review`, `yolo2coco`, `export-classes`.

---

## Project structure

```text
magiclabel/
├── cli.py          # Typer CLI entry point (detect, review, train, predict, yolo2coco, export-classes)
├── annotator.py    # YOLO / YOLO-World detection → label files + classes.txt; predict helper
├── review_app.py   # Gradio review/annotation web app
├── trainer.py      # dataset build + custom model training
├── convertor.py    # YOLO → COCO conversion
└── utils.py        # image discovery + helpers
```

---

## License

Released under the [MIT License](LICENSE).
