Skip to main content

A lightweight Python library for thermal sensing and analytics on ARM Linux platforms

Project description

๐Ÿ”ฅ PyThermal

A lightweight Python library for thermal sensing and analytics on ARM Linux platforms. It provides unified APIs for recording, visualization, and intelligent analysis of thermal data from Hikvision or compatible infrared sensors.


๐ŸŒก๏ธ Features

  • Raw Frame Recording Capture and store radiometric thermal frames (e.g., 96ร—96, 16-bit raw) with timestamps.

  • Colored Visualization Generate pseudo-color thermal images (e.g., 240ร—240 RGB) with adjustable color maps.

  • Live Stream Interface Stream frames in real time, perform temperature conversion and display dynamically.

  • Shared Memory Architecture Efficient zero-copy access to thermal data via shared memory interface.

  • Thermal Object Detection Detect objects based on temperature ranges with clustering support:

    • Temperature-based object detection (default: 31-39ยฐC for human body)
    • Object center detection and clustering
    • Temperature statistics per detected object (min / max / avg)
  • Offline Replay and Analysis (Future Development) Replay recorded sessions for algorithm benchmarking or dataset generation.


๐Ÿš€ Installation

Prerequisites

Before installing the Python package, you need to set up the thermal camera permissions and native runtime:

cd pythermal
./setup.sh

This script will:

  1. Install required system dependencies (cross-compiler, FFmpeg libraries)
  2. Set up USB device permissions for the thermal camera
  3. Compile the native thermal recorder (pythermal-recorder)

After running setup.sh, you may need to:

  • Disconnect and reconnect your thermal camera
  • Log out and log back in (or restart) for permissions to take effect

Install Python Package

Install directly on an ARM Linux device (e.g., Jetson, OrangePi, Raspberry Pi):

uv pip install pythermal

Or from source:

git clone https://github.com/<your-org>/pythermal.git
cd pythermal
uv pip install .

โœ… Bundled Native Runtime The package ships with the native thermal recorder (pythermal-recorder) and required shared libraries (.so files) under pythermal/_native/armLinux/.


๐Ÿง  Quick Start

1. Initialize Thermal Device

The ThermalDevice class manages the thermal camera initialization by starting pythermal-recorder in a separate process and providing access to thermal data via shared memory.

from pythermal import ThermalDevice

# Create and start thermal device
device = ThermalDevice()
device.start()  # Starts pythermal-recorder subprocess and initializes shared memory

# Access shared memory for reading thermal data
shm = device.get_shared_memory()

# When done, stop the device
device.stop()

Or use as a context manager:

with ThermalDevice() as device:
    shm = device.get_shared_memory()
    # Use shared memory...
    # Device automatically stops on exit

2. Live View

Display real-time thermal imaging feed:

from pythermal import ThermalLiveView

viewer = ThermalLiveView()
viewer.run()  # Opens OpenCV window with live thermal feed

Or with a shared device:

from pythermal import ThermalDevice, ThermalLiveView

device = ThermalDevice()
device.start()

viewer = ThermalLiveView(device=device)
viewer.run()  # Uses the shared device

device.stop()

Controls:

  • Press q to quit
  • Press t to toggle between YUYV view and temperature view
  • Move mouse over image to see temperature at cursor position

3. Record Thermal Frames

from pythermal import ThermalRecorder
import time

rec = ThermalRecorder(output_dir="recordings", color=True)
rec.start()              # Starts device and begins recording
rec.record_loop(duration=10)  # Record for 10 seconds
rec.stop()               # Stop recording

This records both:

  • Raw temperature frames (96ร—96, uint16)
  • YUYV visual frames (240ร—240)
  • Colored RGB frames (240ร—240, uint8 RGB) if color=True

4. Access Thermal Data Directly

from pythermal import ThermalDevice, ThermalSharedMemory

device = ThermalDevice()
device.start()

shm = device.get_shared_memory()

# Check for new frame
if shm.has_new_frame():
    # Get metadata
    metadata = shm.get_metadata()
    print(f"Frame {metadata.seq}: {metadata.min_temp:.1f}ยฐC - {metadata.max_temp:.1f}ยฐC")
    
    # Get YUYV frame
    yuyv_frame = shm.get_yuyv_frame()
    
    # Get temperature array (96x96, uint16)
    temp_array = shm.get_temperature_array()
    
    # Get temperature map in Celsius (96x96, float32)
    temp_celsius = shm.get_temperature_map_celsius()
    
    # Mark frame as read
    shm.mark_frame_read()

device.stop()

5. Detect Objects in Thermal Images

Detect objects based on temperature ranges and visualize them with clustering:

from pythermal import ThermalDevice, detect_object_centers, cluster_objects

device = ThermalDevice()
device.start()
shm = device.get_shared_memory()

if shm.has_new_frame():
    metadata = shm.get_metadata()
    temp_array = shm.get_temperature_array()
    
    # Detect objects in temperature range (default: 31-39ยฐC for human body)
    objects = detect_object_centers(
        temp_array=temp_array,
        min_temp=metadata.min_temp,
        max_temp=metadata.max_temp,
        temp_min=31.0,  # Minimum temperature threshold
        temp_max=39.0,  # Maximum temperature threshold
        min_area=50     # Minimum area in pixels
    )
    
    # Cluster nearby objects together
    clusters = cluster_objects(objects, max_distance=30.0)
    
    # Each object contains: center_x, center_y, width, height, area,
    # avg_temperature, max_temperature, min_temperature
    for obj in objects:
        print(f"Object at ({obj.center_x:.1f}, {obj.center_y:.1f}): "
              f"{obj.avg_temperature:.1f}ยฐC")

device.stop()

See examples/detect_objects.py for a complete visualization example.


๐Ÿงฉ Command Line Interface

Command Description
pythermal-preview Live preview with temperature overlay

Example:

pythermal-preview

This will start the thermal device and display a live view window.


๐Ÿงฐ API Overview

Class / Function Purpose
ThermalDevice Manages thermal camera initialization via subprocess and shared memory access
ThermalSharedMemory Reads thermal data from shared memory (YUYV frames, temperature arrays, metadata)
ThermalRecorder Records raw and colored frames to files
ThermalLiveView Displays live thermal imaging feed with OpenCV
FrameMetadata Named tuple containing frame metadata (seq, flag, dimensions, temperatures)
detect_object_centers Detect object centers from temperature map based on temperature range
cluster_objects Cluster detected objects that are close to each other
DetectedObject Dataclass representing a detected object with center, size, and temperature stats

๐Ÿงช Requirements

  • Python โ‰ฅ 3.9
  • ARM Linux environment (Jetson / OrangePi / Raspberry Pi)
  • NumPy, OpenCV (auto-installed via pip)
  • Thermal camera connected via USB
  • Proper USB permissions (set up via setup.sh)

โš™๏ธ Architecture

Native Runtime

The library uses a native binary (pythermal-recorder) that runs as a separate process and writes thermal data to shared memory (/dev/shm/yuyv240_shm). The Python library communicates with this process via shared memory for efficient zero-copy data access.

Bundled Files

The package includes the following native files under pythermal/_native/armLinux/:

pythermal/_native/armLinux/
โ”œโ”€โ”€ pythermal-recorder      # Main thermal recorder executable
โ”œโ”€โ”€ libHCUSBSDK.so            # Hikvision USB SDK library
โ”œโ”€โ”€ libhpr.so                 # Hikvision processing library
โ”œโ”€โ”€ libusb-1.0.so*            # USB library dependencies
โ””โ”€โ”€ libuvc.so                  # UVC library

Shared Memory Layout

The shared memory (/dev/shm/yuyv240_shm) contains:

Offset          Size            Content
0               FRAME_SZ        YUYV frame data (240ร—240ร—2 bytes)
FRAME_SZ        TEMP_DATA_SIZE  Temperature array (96ร—96ร—2 bytes, uint16)
FRAME_SZ+TEMP   ...             Metadata:
                                - seq (4 bytes, uint32)
                                - flag (4 bytes, uint32, 1=new, 0=consumed)
                                - width (4 bytes, uint32)
                                - height (4 bytes, uint32)
                                - min_temp (4 bytes, float)
                                - max_temp (4 bytes, float)
                                - avg_temp (4 bytes, float)
                                - reserved (4 bytes)

Process Management

The ThermalDevice class:

  1. Starts pythermal-recorder as a subprocess
  2. Waits for shared memory to become available
  3. Provides access to thermal data via ThermalSharedMemory
  4. Automatically cleans up the process on exit

Troubleshooting

  • FileNotFoundError: pythermal-recorder not found Make sure you've run setup.sh to compile the native binaries, and that the package was installed correctly.

  • PermissionError: pythermal-recorder is not executable Run chmod +x on the executable, or reinstall the package.

  • TimeoutError: Shared memory did not become available

    • Check that the thermal camera is connected via USB
    • Verify USB permissions are set up correctly (run setup.sh)
    • Try disconnecting and reconnecting the camera
    • Check that no other process is using the thermal camera
  • RuntimeError: Thermal recorder process exited unexpectedly Check the process output for error messages. Common issues:

    • Camera not detected
    • Missing USB permissions
    • Missing shared libraries (check LD_LIBRARY_PATH)

๐Ÿ“ฆ Directory Structure

pythermal/
โ”œโ”€โ”€ pythermal/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ device.py              # ThermalDevice class (manages subprocess)
โ”‚   โ”œโ”€โ”€ thermal_shared_memory.py  # Shared memory reader
โ”‚   โ”œโ”€โ”€ record.py              # ThermalRecorder class
โ”‚   โ”œโ”€โ”€ live_view.py           # ThermalLiveView class
โ”‚   โ”œโ”€โ”€ detections/            # Object detection module
โ”‚   โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”‚   โ””โ”€โ”€ detector.py        # Object detection and clustering functions
โ”‚   โ””โ”€โ”€ _native/
โ”‚       โ””โ”€โ”€ armLinux/
โ”‚           โ”œโ”€โ”€ pythermal-recorder
โ”‚           โ””โ”€โ”€ *.so            # Native libraries
โ”œโ”€โ”€ examples/                  # Example scripts
โ”‚   โ”œโ”€โ”€ live_view.py
โ”‚   โ”œโ”€โ”€ record_thermal.py
โ”‚   โ””โ”€โ”€ detect_objects.py      # Object detection visualization example
โ”œโ”€โ”€ setup.sh                   # Setup script for permissions and compilation
โ”œโ”€โ”€ setup-thermal-permissions.sh
โ”œโ”€โ”€ setup.py                   # Python package setup
โ””โ”€โ”€ README.md

๐Ÿ“š References

@inproceedings{zeng2025thermikit,
  title={ThermiKit: Edge-Optimized LWIR Analytics with Agent-Driven Interactions},
  author={Zeng, Lan and Huang, Chunhao and Xie, Ruihan and Huang, Zhuohan and Guo, Yunqi and He, Lixing and Xie, Zhiyuan and Xing, Guoliang},
  booktitle={Proceedings of the 2025 ACM International Workshop on Thermal Sensing and Computing},
  pages={40--46},
  year={2025}
}

๐Ÿ“„ License

This library is released under the Apache 2.0 License for research and non-commercial use. Only the compiled native library (.so) is shipped; no vendor source or headers are distributed.


๐Ÿ’ก Acknowledgements

๐Ÿซ Developed by AIoT Lab, CUHK
๐Ÿ“ง Device Access: thermal@thingx-tech.com

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pythermal-0.1.3.tar.gz (1.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pythermal-0.1.3-py3-none-any.whl (1.7 MB view details)

Uploaded Python 3

File details

Details for the file pythermal-0.1.3.tar.gz.

File metadata

  • Download URL: pythermal-0.1.3.tar.gz
  • Upload date:
  • Size: 1.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.8

File hashes

Hashes for pythermal-0.1.3.tar.gz
Algorithm Hash digest
SHA256 907aa368dbf89f686b5f98ffdfb432b3a0c6d8dc657cca560b9a30aba9f31576
MD5 642954831cc911c85db7a934c4845e0e
BLAKE2b-256 725d3aedcd0e797d0f38d0a41ac1e4cf6688049fc08dd0847d4404f7902dd1fc

See more details on using hashes here.

File details

Details for the file pythermal-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: pythermal-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.8

File hashes

Hashes for pythermal-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 2cf776ba3e1fed48e196fa37b7fe104b22855108330a8aacd4c7adcce7a9b939
MD5 9f45f3777a8bba1d6f26cdbbd93d23cd
BLAKE2b-256 465f97eb9c5e05d7d2d86b68266fef2b91cc8fb32297018f9b8e337ba7ef4773

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page