EdgeAI_Digit_Recognition/readme.md

64 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# RTSPCamDigitDetection Backend
This service reads frames from one or more RTSP cameras, crops user-defined ROIs (Regions of Interest) containing 7segment digits, runs a TensorFlow Lite digit classifier, and publishes the assembled numeric value to MQTT (e.g., for Home Assistant) [code_file:9][code_file:11].
It also exposes a Flask web UI/API for live video previews, snapshots, and ROI configuration [code_file:9].
## High-Level Architecture
* **`app.py` (Main Service):** Runs the Flask web server and the main processing loop. It drains results from the inference worker, handles MQTT publishing, and manages the rate-limiting logic per camera [code_file:9].
* **`inference.py` (Worker):** A background thread that performs the heavy lifting. It accepts frames, crops the ROIs, runs the TFLite model, and validates results against confidence thresholds and numeric ranges [code_file:11].
* **`manager.py` & `camera.py`:** Handles the RTSP connections, frame buffering, and camera configuration management.
## Configuration
Configuration variables are defined directly at the top of the scripts for simplicity.
### 1. Main Settings (`app.py`)
Edit the top section of `app.py` to change these [code_file:9]:
* **`DEBUG_LOG`** *(bool)*:
* `True`: Enables verbose logging (heartbeats every 5s, per-task timing, detailed skip reasons).
* `False`: Quiet mode. Only prints crucial info (MQTT publishes, connection errors). Warnings about skipped frames are rate-limited to once per minute to prevent log flooding.
* **`DETECTION_INTERVAL`** *(int)*:
* How often (in seconds) to attempt a detection for each camera (Default: `10`).
* **`FRAME_STD_THRESHOLD`** *(float)*:
* Standard Deviation threshold to filter out "bad" frames before inference.
* Frames with contrast lower than this value are skipped.
* *Recommendation:* Set to `0` or `1` if your valid digits are low-contrast. Set higher (e.g., `25`) only if you need to filter out specific gray/green encoding artifacts.
### 2. Inference Settings (`inference.py`)
Edit the top section of `inference.py` to tune the AI [code_file:11]:
* **`CONFIDENCE_THRESHOLD`** *(0.0 - 1.0)*:
* Minimum confidence required for a digit to be accepted.
* *Recommendation:* `0.85` is a good balance to prevent false positives like "1010" while accepting valid digits.
* **`MIN_VALUE` / `MAX_VALUE`** *(int)*:
* Sanity check range. Decoded numbers outside this range (e.g., `1010`) are discarded.
## How It Works (Logic & Logging)
### The "10s vs 60s" Behavior
You might notice that successful detections are logged every **10 seconds**, but errors (like "Value out of range") appear only every **60 seconds**.
* **Success:** The app attempts detection every `DETECTION_INTERVAL` (10s). Every success is logged immediately as INFO.
* **Failure:** If the camera feed is bad or the value is out of range, the error technically occurs every 10s. However, when `DEBUG_LOG = False`, these repetitive warnings are suppressed and only printed **once per minute** to keep the CLI readable [code_file:9].
### MQTT Behavior
* **Topic:** `homeassistant/sensor/RTSPCamDigitDetection/state/<camera_id>`
* **Payload:** `{"value": 42, "confidence": 0.98}`
* **Trigger:** Published only on **successful** detection and validation. Errors are not published to this topic to avoid messing up sensor history.
## API Endpoints
The app runs on port `5000` by default [code_file:9].
| Method | Endpoint | Description |
| :--- | :--- | :--- |
| `GET` | `/` | Web UI Entry point. |
| `GET` | `/video/<camera_id>` | MJPEG stream for live preview. |
| `GET` | `/snapshot/<camera_id>` | Capture a single JPEG snapshot. |
| `GET` | `/cameras` | List configured cameras. |
| `GET` | `/rois/<camera_id>` | Get current ROI definitions. |
| `POST` | `/save_rois` | Save new ROI definitions to disk. |
| `POST` | `/detect_digits` | Manual trigger: runs inference immediately and returns full debug details (JSON). |