Metadata-Version: 2.4
Name: geotiff-cutout
Version: 0.1.10
Summary: Create rectangular pixel cutouts from GeoTIFFs centred on GeoJSON features, with COCO annotation output.
Project-URL: Homepage, https://github.tik.uni-stuttgart.de/ac129613/geotiff_cutout/tree/release
Project-URL: Documentation, https://github.tik.uni-stuttgart.de/ac129613/geotiff_cutout/tree/release#readme
Project-URL: Issues, https://github.tik.uni-stuttgart.de/ac129613/geotiff_cutout/issues
Author-email: Steffen Merseburg <steffen.merseburg@ifp.uni-stuttgart.de>
License: AGPL v3
License-File: LICENSE.txt
Keywords: annotation,coco,crop,cutout,geospatial,geotiff,object-detection,remote-sensing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Scientific/Engineering :: Image Processing
Requires-Python: >=3.10
Requires-Dist: geopandas>=1.1.0
Requires-Dist: numpy>=1.24
Requires-Dist: pillow>=9.0
Requires-Dist: pyproj>=3.5
Requires-Dist: rasterio>=1.5
Requires-Dist: shapely>=2.0
Description-Content-Type: text/markdown

# geotiff-cutout

Create rectangular pixel cutouts from a GeoTIFF centred on GeoJSON
Polygons or Points, with an optional random shift.  All intersecting annotations
are returned in **COCO format** — boxes that extend beyond the cutout edge are
clipped and flagged with `is_truncated`, Polygons will also be returned as segmentation.
Classes must be indicated in the properties of the features.

---

## Installation

```bash
pip install geotiff-cutout
```

> **Note:** `rasterio` and `fiona` depend on GDAL.  On most platforms the
> wheels ship GDAL bundled, so a plain `pip install` is sufficient.  If you
> hit build errors, install via `conda`:
> ```bash
> conda install -c conda-forge rasterio fiona
> pip install geotiff-cutout
> ```

---

## Quick start

### Python API

```python
from geotiff_cutout import make_cutout

# Rectangular cutouts with moderate random shift saved to disk
make_cutouts(
    "image.tif",
    "annotation.geojson",
    "data",
    coco_path="annotations.json",
    cutout_width_px=400,
    cutout_height_px=200,
    random_shift=0.5,
    method="fallback"
)
```

### Command line

```bash
# Square cutouts, default settings
geotiff-cutout ortho.tif annotations.geojson

# Rectangular cutouts with custom shift and output directory
geotiff-cutout ortho.tif annotations.geojson \
    --width 640 --height 480 \
    --shift 0.8 \
    --output my_cutouts/

# Full help
geotiff-cutout --help
```

---

## The `random_shift` parameter

| Value | Effect |
|-------|--------|
| `0.0` | Cutout centred exactly on the feature centroid. |
| `0.5` | Centroid can wander up to half the available slack. |
| `1.0` | Maximum shift: the target bbox may touch (but never cross) the cutout edge. |

Shift is applied independently on each axis, so rectangular cutouts behave
correctly — a wide cutout allows more absolute horizontal shift than a tall one.

---

## COCO output format

Each call returns a standard COCO `dict`:

```json
{
  "images": [{
    "id": 0
    "width": 512,
    "height": 512,
    "file_name": "cutout_<uuid>.png",
    "geotiff_source": "ortho.tif",
    "geojson_source": "annotations.geojson",
    "cutout_col_offset": 340,
    "cutout_row_offset": 120
  }],
  "categories": [{"id": 1, "name": "car"}],
  "annotations": [{
    "id": 0,
    "image_id": 0,
    "category_id": 1,
    "bbox": [12.0, 34.5, 80.0, 60.0],
    "bbox_mode": "xywh",
    "area": 4800.0,
    "iscrowd": 0,
    "is_truncated": false,
    "original_bbox": [12.0, 34.5, 80.0, 60.0],
    "segmentations":[[12.0, 34.5, ...,  80.0, 60.0]],
    "origina_segmentations":[[12.0, 34.5, ...,  80.0, 60.0]]
  }]
}
```
**all coordinates in coco annotation are local image pixel coordinates**
**`bbox`** is the annotation clipped to the cutout boundary (`[x, y, w, h]` in
local cutout pixels).  
**`original_bbox`** is the full, unclipped box (may have negative coordinates
or values exceeding the cutout dimensions for truncated boxes).  
**`segmentation`** similar to `bbox` but Polygon segemnt if input was not Point.
**`original_segmentation`** similar to `original_bbox` but Polygon segemnt if input was not Point.
**`is_truncated`** is `true` when the box was clipped.

The category name is read from the first matching GeoJSON property key:
`category` → `class` → `label` → `"object"` (fallback).

---

## License

AGPL 3
