An open API service indexing awesome lists of open source software.

https://github.com/pyronear/pyro-engine

Wildfire detection on edge devices
https://github.com/pyronear/pyro-engine

docker image-classification onnxruntime python raspberry-pi wildfire

Last synced: 4 days ago
JSON representation

Wildfire detection on edge devices

Awesome Lists containing this project

README

          

![PyroNear Logo](docs/source/_static/img/pyronear-logo-dark.png)



CI Status


Documentation Status


Test coverage percentage


black





PyPi Version


DockerHub version

Supported Python versions
license

# PyroEngine repository

This repository contains two main components used in Pyronear wildfire detection deployments: `pyroengine` and `pyro_camera_api`

| Directory | Description |
| ------------------ | ------------------------------------------------------------------------- |
| `pyroengine/` | Detection engine that runs the wildfire model on edge devices |
| `pyro_camera_api/` | Camera control API that exposes a unified interface for multiple adapters |
| `scripts/` | Shell scripts for deployment and debugging |
| `src/` | Helper scripts for camera control, focus, calibration and experiments |
| `tests/` | Test suite for the detection engine |

Both components can run independently or together in the same deployment.

---

## PyroEngine: wildfire detection on edge devices

PyroEngine provides a high level interface to use deep learning models in production while being connected to the alert API.

### Quick example

```python
from pyroengine.core import Engine
from PIL import Image

engine = Engine()

im = Image.open("path/to/your/image.jpg").convert("RGB")

prediction = engine.predict(im)
```

---

## PyroCamera API: unified camera control

The `pyro_camera_api` package provides a REST API and a Python client to control cameras and retrieve images in a unified way.

The API supports multiple camera adapters through a common abstraction:

* `reolink` adapter, for Reolink PTZ or static cameras
* `linovision` adapter, for Linovision/Hikvision PTZ cameras using ISAPI
* `rtsp` adapter, for RTSP streams
* `url` adapter, for HTTP snapshot URLs
* `mock` adapter, for development and tests

Each adapter has its own class and inherits from the same base interface. The system selects the correct implementation at runtime based on the `adapter` field in `credentials.json`. The API routes are the same for all camera types. PTZ cameras use pose and movement, other cameras ignore pose parameters without failing.

### Simple API usage example

```python
from pyro_camera_api_client import Client

client = Client("http://localhost:8000")

# Move a PTZ camera to a pose
client.move("ptz_camera_1", pose=2)

# Get a snapshot as bytes
image_bytes = client.snapshot("url_camera_1")
```

---

## Setup

Python 3.11 or higher and `pip` or `conda` are required.

### Developer installation

```bash
git clone https://github.com/pyronear/pyro-engine.git
pip install -e pyro-engine/.
```

### Environment variables

Deployments usually rely on a `.env` file. A `.env.example` is provided at the root of the repository as a reference:

```text
API_URL=https://api.pyronear.org
CAM_USER=my_dummy_login
CAM_PWD=my_dummy_pwd
MEDIAMTX_SERVER_IP=1.2.3.4
PYRO_ENGINE_VERSION=latest
```

`PYRO_ENGINE_VERSION` controls which Docker image tag is pulled for both services (defaults to `latest` if unset).

### Data directory

A `./data` directory is expected with at least:

* `credentials.json`, see [Camera configuration ](#camera-configuration-and-backends) to understand how to fill it
* optionally `model.onnx` to override weights from Hugging Face
* optionally `config.json` to override model configuration

---

## Camera configuration and adapters

The camera configuration is stored in `credentials.json`. Each key represents a camera identifier and the entry defines how to access and control it.

The important field for the camera API is:

* `adapter` which selects the camera implementation

Other fields such as `type`, `pose_ids`, `poses`, or `bbox_mask_url` are used by the engine and the API.

`pose_ids` contains the pose IDs from the pyro-api database. For static cameras it is a list with a single element; for PTZ cameras each entry corresponds positionally to the matching physical preset in `poses`. If `bbox_mask_url` is set, occlusion mask files are fetched at `{bbox_mask_url}_{pose_id}.json`.

Below is one generic example for each adapter: `url`, `rtsp`, `reolink` static, `reolink` PTZ and `mock`.
```json
{
"url_camera_1": {
"name": "url_camera_1",
"adapter": "url",
"url": "http://user:password@camera-host:1234/cgi-bin/snapshot.cgi",
"pose_ids": [10],
"id": "10",
"bbox_mask_url": "",
"poses": [],
"token": "JWT_TOKEN_HERE",
"type": "static"
},

"rtsp_camera_1": {
"name": "rtsp_camera_1",
"adapter": "rtsp",
"rtsp_url": "rtsp://user:password@camera-host:554/live/STREAM_ID",
"pose_ids": [11],
"id": "11",
"bbox_mask_url": "https://example.com/occlusion-masks/rtsp_camera_1",
"poses": [],
"token": "JWT_TOKEN_HERE",
"type": "static"
},

"192.168.1.11": {
"name": "reolink_static_1",
"adapter": "reolink",
"type": "static",
"pose_ids": [12],
"id": "12",
"poses": [],
"bbox_mask_url": "https://example.com/occlusion-masks/reolink_static_1",
"token": "JWT_TOKEN_HERE"
},

"192.168.1.12": {
"name": "reolink_ptz_1",
"adapter": "reolink",
"type": "ptz",
"id": "13",
"poses": [0, 1, 2, 3],
"pose_ids": [20, 21, 22, 23],
"bbox_mask_url": "https://example.com/occlusion-masks/reolink_ptz_1",
"token": "JWT_TOKEN_HERE"
},

"192.168.1.13": {
"name": "linovision_ptz_1",
"adapter": "linovision",
"type": "ptz",
"poses": [0, 1, 2, 3],
"pose_ids": [30, 31, 32, 33],
"azimuth_offset_deg": 90,
"bbox_mask_url": "https://example.com/occlusion-masks/linovision_ptz_1",
"token": "JWT_TOKEN_HERE"
},

"mock_camera_1": {
"name": "mock_camera_1",
"adapter": "mock",
"type": "static",
"pose_ids": [0],
"id": "14",
"poses": [],
"bbox_mask_url": "",
"token": "JWT_TOKEN_HERE"
}
}

```

These examples are only for illustration. Real deployments use real URLs and real tokens generated by the alert API. For Linovision/Hikvision, `username`/`password` override the global `CAM_USER`/`CAM_PWD`, `azimuth_offset_deg` aligns camera coordinates to real azimuths, and `snapshot_channel`/`ptz_channel` let you pick the right ISAPI channels.

---

## Documentation

The full package documentation is available here:

[https://pyronear.org/pyro-engine/](https://pyronear.org/pyro-engine/)

It covers engine usage, configuration and deployment details.

---

## Contributing

Please refer to [`CONTRIBUTING`](CONTRIBUTING.md) if you wish to contribute to this project.

---

## License

Distributed under the Apache 2 License. See [`LICENSE`](LICENSE) for more information.