Metadata-Version: 2.4
Name: hiktemp
Version: 0.2.0
Summary: Minimal radiometric temperature extraction from Hikvision thermal cameras
Author: xynogen
License-Expression: MIT
Project-URL: Homepage, https://github.com/xynogen/hiktemp
Project-URL: Repository, https://github.com/xynogen/hiktemp
Project-URL: Issues, https://github.com/xynogen/hiktemp/issues
Keywords: hikvision,thermal-camera,isapi,radiometric,temperature
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
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: Topic :: Scientific/Engineering
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.28
Requires-Dist: numpy>=1.23
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"

# hiktemp

Minimal radiometric temperature extraction from Hikvision thermal cameras via ISAPI.  
No SDK required. Only depends on `requests` and `numpy`.

## Install

```bash
pip install hiktemp
```

Or from source:

```bash
git clone https://github.com/xynogen/hiktemp
cd hiktemp
pip install -e .
```

## Usage

```python
from hiktemp import hiktemp

frame = hiktemp("http://192.168.1.1", "admin", "password")

frame.matrix          # np.ndarray (H, W) float32 — per-pixel °C
frame.jpeg            # bytes — raw JPEG from camera (AGC, display only)
frame.meta            # dict  — camera descriptor
frame.min             # float — global min °C
frame.max             # float — global max °C
frame.mean            # float — global mean °C
frame.std             # float — global std °C
frame.hotspot()       # (row, col) — global hotspot
frame.coldspot()      # (row, col) — global coldspot

# band filter — lo/hi passed at call time
frame.hotspot(lo=28, hi=29)    # hotspot within band
frame.coldspot(lo=28, hi=29)   # coldspot within band
frame.masked(lo=28, hi=29)     # matrix with out-of-band pixels = NaN
frame.alpha(lo=28, hi=29)      # float32 (H,W) quintic smoothstep mask 0–1
```

Visualization is left to the caller:

```python
import matplotlib.pyplot as plt

plt.imshow(frame.matrix, cmap="inferno")
plt.colorbar(label="°C")
plt.show()

# with band mask — color from temperature, transparency from mask
import numpy as np
import matplotlib.pyplot as plt

norm = (frame.matrix - frame.matrix.min()) / (frame.matrix.max() - frame.matrix.min())
rgba = plt.get_cmap("inferno")(norm)       # color mapped from temperature
rgba[:, :, 3] = frame.alpha(lo=28, hi=29)  # alpha from band mask
plt.imshow(rgba)
plt.show()
```

Reuse session for continuous polling — once authenticated, no need to pass credentials again:

```python
import requests
from requests.auth import HTTPDigestAuth

session = requests.Session()
session.auth = HTTPDigestAuth("admin", "password")

while True:
    frame = hiktemp("http://192.168.1.1", session=session)
    print(frame.hotspot())
```

## Requirements

- Python >= 3.10
- `requests >= 2.28`
- `numpy >= 1.23`

## Tested on

- DS-2TD2138-10/QY (384×288, float32 °C, channel 1)
