File size: 2,135 Bytes
df4e114 93754f2 df4e114 93754f2 df4e114 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | """Typer CLI to annotate an image with bounding boxes from a JSON file.
Run with uv, e.g.::
uv run python annotate_cli.py assets/example_0_in.jpg assets/example_0.json
The JSON must be a list of object dicts, each with a pascal_voc ``boundingBox``
(``{x0, y0, x1, y1}``); see ``assets/example_0.json``.
"""
from pathlib import Path
from typing import Optional
import typer
from loguru import logger
import pilbox
app = typer.Typer(add_completion=False, help=__doc__)
@app.command()
def main(
image: Path = typer.Argument(
..., exists=True, dir_okay=False, readable=True, help="Source image path."
),
annotations: Path = typer.Argument(
..., exists=True, dir_okay=False, readable=True, help="JSON annotations path."
),
output: Optional[Path] = typer.Option(
None, "--output", "-o", help="Output path (default: <image>_out.jpg)."
),
label_key: str = typer.Option(
"object_id", "--label-key", help="Object key drawn as each box's label."
),
color_key: str = typer.Option(
"object_id", "--color-key", help="Object key used to color-group boxes."
),
mask_key: str = typer.Option(
"b64_mask",
"--mask-key",
help="Object key holding a base64 PNG mask (empty disables masks).",
),
mask_alpha: float = typer.Option(
0.5, "--mask-alpha", help="Mask overlay opacity in [0, 1]."
),
width: int = typer.Option(3, "--width", help="Box outline width in pixels."),
font_size: int = typer.Option(20, "--font-size", help="Label font size."),
):
"""Draw bounding boxes from ANNOTATIONS onto IMAGE and save the result."""
out_path = output or image.with_name(f"{image.stem}_out.jpg")
logger.info(f"annotating {image} with {annotations} -> {out_path}")
pilbox.annotate_file(
str(image),
str(annotations),
str(out_path),
label_key=label_key,
color_key=color_key,
mask_key=mask_key,
mask_alpha=mask_alpha,
width=width,
font_size=font_size,
)
logger.info(f"saved {out_path}")
if __name__ == "__main__":
app()
|