Metadata-Version: 2.4
Name: drawbox-cv
Version: 0.1.0
Summary: A modular, interactive bounding box frame labeler with zoom and pan support.
License: MIT
Requires-Python: >=3.8
Requires-Dist: numpy>=1.20.0
Requires-Dist: opencv-python>=4.8.0.0
Requires-Dist: pillow>=10.0.0
Description-Content-Type: text/markdown

# DrawBox-CV

A modular, cross-platform, Tkinter-based interactive frame annotator for computer vision datasets. 

This tool is designed to work like a desktop-based, lightweight **Roboflow** editor, enabling real-time frame-by-frame labeling with mouse zoom and pan, dynamic color mapping, unlimited custom classes, and multi-format labels export.

---

## Key Features

- **Tkinter GUI Engine**: Replaces raw OpenCV windows with a robust Tkinter interface that natively supports resizing to fit any monitor resolution.
- **Dynamic Zoom & Pan**:
  - **Zoom**: Scroll wheel (zoom is centered directly around your mouse cursor).
  - **Pan**: Middle-mouse drag (click and drag the wheel).
- **Roboflow-Style Editing**: Always in editing mode! No need to toggle modes.
  - **Draw**: Left-click and drag on an empty area.
  - **Move**: Left-click and drag inside an existing box.
  - **Resize**: Left-click and drag the white corner handles.
  - **Delete**: Right-click any box, or press `Delete`/`Backspace` key on selected box.
  - **Undo**: Press `Ctrl+Z` to undo the last drawn box.
- **Unlimited Custom Classes**: Neglects the old 0-9 class limit. You can add new classes dynamically via the sidebar.
- **Dynamic Color Assignments**: Automatically generates visually distinct, high-contrast colors using the Golden Ratio in HSV space for every new class.
- **Flexible Multi-Format Exports**: Saves bounding box annotations to any combination of formats simultaneously:
  - **YOLO**: Saves as standard `.txt` files with normalized `[class_id, x_center, y_center, width, height]` format.
  - **COCO**: Updates a single unified `annotations.json` file inside the COCO subdirectory.
  - **Pascal VOC**: Saves standard XML annotation documents.
  - **TF**: Saves custom normalized `[class_id, xmin, ymin, xmax, ymax]` text files.
- **Optional Object Cropping**: Crop bounding boxes and save them into directories categorized by class names.

---

## Professional Package Structure

This library uses the industry-standard `src` layout for Python packaging:

```
New/
├── pyproject.toml              # Build backend and dependencies (using >= versions)
├── README.md                   # Installation & usage guide
└── src/
    └── drawbox/                # Package root for 'import drawbox'
        ├── __init__.py         # Package entry points
        ├── __main__.py         # Interactive CLI runner
        ├── app.py              # Tkinter main GUI window
        ├── canvas.py           # Zoom/Pan interactive canvas
        ├── dataset.py          # Images/crops dataset orchestrator
        ├── box.py              # Bounding box coordinates translation
        ├── classes.py          # ClassRegistry management
        ├── config.py           # Custom output path configuration
        ├── colors.py           # Golden ratio HSV color generator
        └── formats/            # Exporters subpackage
            ├── __init__.py     # Registry and registry helpers
            ├── base.py         # Abstract base format class
            ├── coco_format.py  # COCO dataset writer
            ├── tf_format.py    # TF layout exporter
            ├── voc_format.py   # Pascal VOC XML exporter
            └── yolo_format.py  # YOLO annotation exporter
```

---

## Installation & Setup

Ensure you have Python 3.8 or newer installed on your system.

### 1. Install System Prerequisites (Linux Only)
On Linux systems (e.g., Ubuntu/Debian), Tkinter requires system-level libraries. Install them via your package manager:
```bash
sudo apt update
sudo apt install python3-tk
```
*(Windows and macOS include Tkinter by default during Python installation).*

### 2. Install from Local Code
Navigate to the root directory where `pyproject.toml` is located (the `New/` directory) and run:
```bash
pip install .
```
This automatically installs the package `drawbox-cv` along with all necessary dependencies (`opencv-python`, `pillow`, `numpy`) matching version compatibility (`>=`).

For development (changes in code will reflect immediately), install it in editable mode:
```bash
pip install -e .
```

---

## How to Run

Once installed, you can launch the app from any folder in your terminal simply by typing:
```bash
drawbox
```

Alternatively, you can run the package directly from source without installation:
```bash
python -m src.drawbox
```

### Walkthrough of Interactive Prompts:
1. **Input frames directory path**: Path to the folder containing your source images (`.jpg`, `.png`, etc.).
2. **Base output directory path**: Path to where you want all results to be saved (e.g., `output`). Default is `output`.
3. **Starting frame index**: Frame number to start labeling from (default: `0`).
4. **Initial label file path**: If you have a file with initial labels (e.g., `temp.txt`), provide the path. Press Enter to skip.
5. **Output format(s)**: Comma-separated list of formats you wish to save. For example, `yolo,coco` or `tf,yolo,voc`. Default is `yolo`.
6. **Carry over edited labels**: Carry labels from the previous frame to the next (`y`/`n`).
7. **Save cropped bounding boxes**: Crop objects and save them under separate subdirectories for each class (`y`/`n`).

---

## Output Layout

All files are structured inside your specified base output directory (e.g. `output`):
- `output/classes.txt`: Contains your class list ordered by class ID.
- `output/<format_name>/`: Specific folder for each selected label format containing the annotations (e.g., `output/yolo/`, `output/voc/`). Labels match your original frame file names (e.g. `image_1.txt`, `image_1.xml`).
- `Crops folder` (either `output/crops/` or your custom folder): Subfolders (e.g. `0_class_0/`) containing crop PNGs.

---

## Keyboard Shortcuts Map

| Key | Description |
| --- | --- |
| **`s` / `S`** / **`Enter`** | Save labels and move to **Next** frame |
| **`k` / `K`** / **`Right Arrow`** / **`Down Arrow`** | Skip current frame without saving, and move to **Next** frame |
| **`a` / **`Left Arrow`** / **`Up Arrow`** | Move back to **Previous** frame |
| **`f` / `F`** | Center and fit the image to the window size |
| **`Ctrl + Z`** | Undo the last change |
| **`Ctrl + Shift + Z`** | Redo the last change |
| **`r`** | Copy previous frame's labels to current frame |
| **`Ctrl + Left Click`** | Select bounding box and its class label (draws box inside box easily) |
| **`Delete` / `Backspace`** | Delete the currently selected bounding box |
| **`0` – `9`** | Quick-select corresponding class IDs |
| **`q` / `Esc`** | Close window and exit app |
