Metadata-Version: 2.4
Name: dannotate
Version: 0.1.1
Summary: Desktop image annotation tool for computer-vision datasets
Author: DAnnotate contributors
License: Apache-2.0
Keywords: annotation,computer vision,datasets,image labeling
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Image Processing
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: pydantic>=2.7
Provides-Extra: desktop
Requires-Dist: PyQt6>=6.7; extra == "desktop"
Provides-Extra: backend
Requires-Dist: alembic>=1.13; extra == "backend"
Requires-Dist: fastapi>=0.111; extra == "backend"
Requires-Dist: numpy>=1.26; extra == "backend"
Requires-Dist: opencv-python-headless>=4.10; extra == "backend"
Requires-Dist: pandas>=2.2; extra == "backend"
Requires-Dist: passlib[bcrypt]>=1.7; extra == "backend"
Requires-Dist: pillow>=10.3; extra == "backend"
Requires-Dist: pydantic-settings>=2.3; extra == "backend"
Requires-Dist: python-jose[cryptography]>=3.3; extra == "backend"
Requires-Dist: python-multipart>=0.0.9; extra == "backend"
Requires-Dist: sqlalchemy>=2.0; extra == "backend"
Requires-Dist: uvicorn[standard]>=0.30; extra == "backend"
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"

# DAnnotate

Desktop image annotation for building computer-vision datasets.

DAnnotate is a PyQt6 application for annotating images with bounding boxes, polygons, points, and lines. Labels are saved beside their source images as JSON, XML, or YOLO TXT files, so a project needs no database. An optional FastAPI backend is included for teams that need a server, database, or programmatic import/export.

## Highlights

- Annotate with boxes, polygons, points, and lines.
- Organize annotations by named classes and colors.
- Autosave annotations beside each source image.
- Store lossless geometry in JSON or XML.
- Export detection and segmentation annotations in YOLO format.
- Undo, redo, relabel, and delete annotations per image.
- Convert an entire folder between supported formats.
- Use the desktop app independently from the optional backend.

## Choose a workflow

| Workflow | Best for | Dependencies |
| --- | --- | --- |
| Desktop annotation tool | Local image annotation | Python 3.10+ and PyQt6 |
| Backend and REST API | Teams, databases, and automation | Backend dependencies from `requirements.txt` |

## Quick start: desktop app

### Requirements

- Python 3.10 or newer (Python 3.12 recommended)
- PyQt6

### Install from PyPI

Install the desktop application directly from PyPI:

```bash
python -m pip install "dannotate[desktop]"
```

Launch the application:

```bash
dannotate
```

For local development from a cloned repository, run these commands from the project root:

```bash
python -m venv .venv
```

Activate the virtual environment:

```powershell
# Windows PowerShell
.venv\Scripts\Activate.ps1
```

```bash
# macOS or Linux
source .venv/bin/activate
```

Install the desktop dependencies and launch DAnnotate:

```bash
python -m pip install -e ".[desktop]"
python -m app.desktop.main
```

### First run

1. Select **Open Folder** or press `Ctrl+O`, then choose a folder of images.
2. Click **+** in the **Classes** panel to add a class and choose its color.
3. Select a drawing tool and start annotating.
4. Use **Prev** and **Next** or press `A` and `D` to move between images.

Annotations are saved automatically beside each image.

## Publishing files

The PyPI project description is generated from this README. To publish the installable desktop application without uploading the source archive, build and upload only the wheel:

```bash
python -m build --wheel
python -m twine check dist/*.whl
python -m twine upload dist/*.whl
```

The wheel is still the installable application and contains the package code required by `dannotate`. PyPI cannot provide an installable Python application without distributing its code. Do not upload `dist/*.tar.gz` if you do not want to publish the source archive.

## Using the annotation tool

### Tools

| Tool | Shortcut | How to use |
| --- | --- | --- |
| Select | `V` | Default mode; pan with the middle mouse button. |
| Bounding box | `B` | Click and drag to draw a rectangle. |
| Polygon | `P` | Click to add vertices, then click the first marker or press `Enter` to close. Press `Esc` to cancel. |
| Point | `O` | Click once to place a point. |
| Line | `L` | Click the start point, then click the end point. |

Zoom with the mouse wheel, the canvas zoom buttons, or `Ctrl++`, `Ctrl+-`, and `Ctrl+0` to fit the image. The status bar shows the active tool, cursor coordinates, image dimensions, and zoom level.

### Polygon drawing

Each click adds a vertex and an edge. A dashed rubber-band line follows the cursor. After at least three points have been added, move near the first marker and click to close the polygon, or press `Enter`. Press `Esc` to discard the shape.

### Classes

- **Add:** Click **+**, then enter a name and choose a color.
- **Edit:** Double-click a class, or right-click it and select **Edit**. Renaming or recoloring updates annotations of that class on the current image.
- **Delete:** Right-click a class and select **Delete**. Existing annotations keep their label; only the palette entry is removed.

Select a class before drawing so new annotations receive its label and color. If no class exists, DAnnotate prompts you to create one.

### Annotations

Every annotation appears in the right panel with its class color and shape type.

- **Relabel:** Right-click an annotation and select **Change class...**, or double-click it.
- **Delete:** Select an annotation and press `Delete`, use the trash button, or choose **Delete** from its context menu.
- **Undo and redo:** Press `Ctrl+Z` to undo and `Ctrl+Y` or `Ctrl+Shift+Z` to redo. History is maintained per image for adds, deletes, and relabeling.

## Saving and file formats

Choose **JSON**, **XML**, or **TXT** with the **Save As** controls at the bottom of the left rail. The selected format is written beside the image using the same base name. For example, annotating `street.jpg` creates `street.json`, `street.xml`, or `street.txt`.

Switching formats resaves the current image and removes the other sidecar formats, so each image has one active annotation file. Saving occurs automatically after edits, undo/redo, image changes, and when the application closes. You can also save with **File > Save** or `Ctrl+S`.

### JSON and XML

JSON and XML are lossless formats. They store class names, colors, and complete geometry for rectangles, polygons, lines, and points in absolute pixel coordinates.

```json
{
  "image": "street.jpg",
  "width": 1280,
  "height": 720,
  "annotations": [
    {
      "class": "car",
      "color": "#ef4444",
      "shape": {
        "type": "rectangle",
        "x": 10,
        "y": 20,
        "width": 100,
        "height": 60
      }
    }
  ]
}
```

### YOLO TXT

TXT uses standard YOLO coordinates normalized to the range `0..1`. A folder-level `classes.txt` file maps class IDs to names.

```text
# street.txt
0 0.532306 0.366320 0.681087 0.732640

# classes.txt
car
```

- **Boxes:** `class_id x_center y_center width height`
- **Polygons:** `class_id x1 y1 x2 y2 ...`

YOLO does not support colors, points, or lines. Those annotations are skipped when saving to TXT, with a status message. Keep them in JSON or XML when they are needed. On load, class names come from `classes.txt` and colors are derived from a stable palette.

All coordinates use a top-left pixel origin. When a folder is reopened, DAnnotate scans its sidecar files and rebuilds the Classes panel.

## Batch conversion

Use **Save As** to convert the current image, or convert a whole folder from the command line:

```bash
python scripts/convert_annotations.py --dir /path/to/images --to yolo
```

The target format can be `json`, `xml`, or `yolo`. YOLO conversion needs image dimensions, which are read with Pillow:

```bash
python -m pip install pillow
```

The conversion primitives live in `app/desktop/formats.py` and `app/desktop/sidecar.py`.

## Project layout

```text
AI_Vision_Annotation_Studio/
├── app/
│   ├── desktop/                 # PyQt6 annotation tool
│   │   ├── main.py              # application entry point
│   │   ├── main_window.py       # window, panels, and annotation logic
│   │   ├── canvas.py            # drawing surface, zoom, and pan
│   │   ├── sidecar.py            # load/save files beside images
│   │   ├── formats.py            # JSON, XML, and TXT serializers
│   │   └── theme.py              # dark theme and design tokens
│   ├── core/                    # universal schema and geometry
│   ├── database/                # SQLAlchemy models and repositories
│   ├── services/                # project, annotation, and QA services
│   ├── exporters/               # COCO, YOLO, and Pascal VOC writers
│   ├── importers/               # COCO and YOLO readers
│   ├── ai/                      # detector backend interfaces
│   └── api/                     # FastAPI app and routers
├── tests/                       # test suite
├── scripts/                     # utility scripts
├── docs/                        # design and architecture documentation
├── requirements-desktop.txt     # desktop-only dependencies
├── requirements.txt             # backend dependencies
└── pyproject.toml               # packaging and optional extras
```

## Optional backend and REST API

The backend is separate from the desktop application and is only needed for a server, database, or programmatic import/export.

Install the backend and development dependencies:

```bash
python -m pip install -e ".[dev]"
```

Optionally seed the database, then start the API:

```bash
python scripts/seed_db.py
uvicorn app.api.main:app --reload
```

Open the interactive API documentation at [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs). The root URL does not have a page by design.

The backend includes COCO, YOLO, and Pascal VOC exporters; COCO and YOLO importers; plugin registries; and a universal annotation schema. The desktop JSON files contain the class, color, and geometry data needed by these exporters.

Run the test suite with:

```bash
pytest
```

The persistence tests in `tests/test_sidecar.py` cover JSON, XML, and TXT round trips, sidecar cleanup during format switches, and class rebuilding.

## Documentation

The `docs/` directory contains documentation for architecture, database schema, API specification, the universal annotation schema, folder structure, UI wireframes, import and export, roadmap, deployment, security, performance, diagrams, and risks.

## Troubleshooting

### `ModuleNotFoundError: No module named 'app'`

Run commands from the project root, for example:

```bash
python -m app.desktop.main
```

The seed script also bootstraps the project path when needed.

### `{"detail":"Not Found"}` in the browser

That response is expected at the API root. Open `/docs` instead. The desktop application does not require the API.

### Qt platform plugin or display errors

The desktop app needs a graphical session. On headless Linux, use a real display or Xvfb.

### PyQt6 installation issues

Upgrade pip and verify that Python 3.10 or newer is active:

```bash
python -m pip install --upgrade pip
```

PyQt6 provides QtSvg, which DAnnotate uses for toolbar icons.

## License

Apache-2.0
