The SARA Thermal Reading provides an automated process to get the temerature in a chosen polygon in a thermal image.
The dependencies used for this package are listed in pyproject.toml and pinned in uv.lock. This ensures our builds are predictable and deterministic. This project uses uv for dependency management:
uv lock
To update the dependencies to the latest versions, run:
uv lock --upgrade
For the thermal reading to run, we need a reference image and reference polygon located in a blob store.
Both the image and polygon needs to be stored in a container named installation_code and a folder named tagId_inspectionDescription. For an example see the saradev, saradevthermalref storage account.
Install with uv sync --extra dev
Run tests with uv run pytest .
SOURCE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=ht ...
DESTINATION_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=ht ...
REFERENCE_STORAGE_CONNECTION_STRING=ht ...
Draw polygon directly on image
python utils_cli.py create-polygon path/to/image.fffWill by default save to reference_polygon.json in the current directory
Draw polygon on thermal reference image, and save it to blob
python utils_cli.py create-polygon-cloud blobstorageaccountname "tagId" "inspectiondescription"Show reference polygon on thermal reference image
python utils_cli.py show-polygon-cloud blobstorageaccountname "tagId" "inspectiondescription"python utils_cli.py plot-fff path/to/image.fff --polygon-json-path path/to/reference_polygon.jsonpython utils_cli.py plot-current-reference-image-and-polygon \
--installation-code "hua" --tag-id testtag --inspection-description testdescpython utils_cli.py run-fff-workflow --polygon-path example-data/asset-example/polygon.json --reference-image-path example-data/asset-example/thermal_image.fffgraph TD
subgraph Inputs
A[Source Thermal Image]
C[Reference Thermal Image]
B[Reference Polygon .json]
end
subgraph Preprocessing
D[Normalize temp range]
E[Convert to uint8]
F[CLAHE]
end
subgraph "Image Matching & Alignment"
G["Phase Corr. + Hanning window"]
H["Translation (dx, dy)"]
J["Shift polygon by (dx, dy)"]
end
subgraph "Temperature Extraction"
K["Create mask from polygon"]
L[Apply mask to source image]
M["Percentile(pixels, 95)"]
end
A --> D
C --> D
D --> E --> F
F -->|"preprocessed source"| G
F -->|"preprocessed reference"| G
G --> H
H --> J
B --> J
J --> K
A -->|"raw float64 (°C)"| L
K --> L --> M
M --> N([P95 Temperature Output])