Skip to main content

thermophysio

A Python library for extracting, analysing, and cross-correlating skin temperature time-series from FLIR thermal infrared camera recordings of human participants during psychophysiology experiments.


Overview

The pipeline extracts temperature signals from anatomically defined regions of interest (ROIs) on the face, scalp, and neck, then asks: does the difference in a thermal feature between two regions correlate with task activation?

Three camera configurations are supported:

Camera Landmark detector Regions
Frontal (face-forward) MediaPipe FaceLandmarker (468 landmarks) 13 facial/neck ROIs
Back-of-head YOLOv8 pose (ear keypoints) 11 cranial/neck ROIs
Dual side-profile YOLOv8 pose (eye, ear, nose) 24 bilateral ROIs

Installation

pip install thermophysio

MediaPipe and Ultralytics (YOLOv8) are installed as dependencies. YOLOv8 weights (yolov8n-pose.pt) are downloaded automatically on first use.

For development / editable install from source:

git clone https://github.com/RauwP/thermophysio
cd thermophysio
pip install -e .

Experiment Types

Type Experiments Camera Regions
Faces Exp01–05, Exp08 Back 11
GoNoGo Exp06, Exp09, Exp11 Frontal 13
Words Exp07, Exp10, Exp12, Exp21 Frontal 13
CORSI Exp13–20 Frontal 13
LogicalVsIllogical Exp22–24 Dual 24

Workflow

Step 1 — Extraction (interactive, per session)

from thermophysio import extract_back, extract_frontal, extract_profile

# Back-of-head camera (Faces experiment)
extract_back(
    img_dir="Experiments/Exp01-Faces",
    out_dir="Calc_Experiments/Exp01-Faces",
    model="yolov8n-pose.pt"
)

# Frontal camera (GoNoGo, Words, CORSI)
extract_frontal(
    img_dir="Experiments/Exp06-GoNoGo",
    out_dir="Calc_Experiments/Exp06-GoNoGo"
)

# Dual side-profile (LogicalVsIllogical)
extract_profile(
    dir_a="Experiments/Exp22-LogicalVsIllogical/CamA",
    dir_b="Experiments/Exp22-LogicalVsIllogical/CamB",
    out_dir="Calc_Experiments/Exp22-LogicalVsIllogical",
    model="yolov8n-pose.pt"
)

Each call opens a GUI for entering block timings, then processes all frames automatically. Outputs land in:

Calc_Experiments/Exp01-Faces/
  raw/                      session_meta.json + overlays/ + pixels/
  stats.csv                 10 features × all ROIs × all timepoints
  stats_resampled.csv       uniformly resampled at dt=5 s
  analysis/
    ccf_table.csv           all (feature × pair) CCF results, ranked
    top10_leaderboard.png   top-10 bar chart with Bartlett CI
    top10_ccf_grid.png      5×2 grid of top-10 full CCF curves
    plots/                  individual CCF plots + per-feature grids

If extraction was done separately into Processed_Experiments/, run only the analysis pipeline:

from thermophysio._pipeline import run_pipeline

run_pipeline(
    raw_dir="Processed_Experiments/Exp01-Faces",
    out_dir="Calc_Experiments/Exp01-Faces"
)

Step 2 — Meta-Analysis (post-hoc, across runs of same type)

python -m thermophysio.FLIR_Meta_Analysis \
    Calc_Experiments/Exp01-Faces/analysis/ccf_table.csv \
    Calc_Experiments/Exp02-Faces/analysis/ccf_table.csv \
    Calc_Experiments/Exp03-Faces/analysis/ccf_table.csv \
    Calc_Experiments/Exp04-Faces/analysis/ccf_table.csv \
    Calc_Experiments/Exp05-Faces/analysis/ccf_table.csv \
    Calc_Experiments/Exp08-Faces/analysis/ccf_table.csv \
    --out Calc_Experiments/Meta_Faces \
    --label "Faces" \
    --min-runs 2

Outputs: leaderboard PNG, table PNG, full AI-readable markdown report.


Repository Structure

thermophysio/                 Installable package
  __init__.py                 Public API: extract_frontal / extract_back / extract_profile
  _pipeline.py                Orchestrator: build_csv → resample → analyse → summarise
  Back_FLIR_Extractor.py      YOLOv8 back-of-head pipeline
  Frontal_FLIR_Extractor.py   MediaPipe frontal pipeline
  Dual_FLIR_Extractor.py      YOLOv8 dual side-profile pipeline
  FLIR_Stats_to_CSV.py        NPZ → 10-feature stats CSV
  FLIR_TimeSeries.py          Irregular → uniform time resampling
  FLIR_CrossROI_Analysis.py   Bartlett-corrected CCF analysis + plots
  FLIR_Top_Correlations.py    Top-N leaderboard and CCF grid (per session)
  FLIR_Meta_Analysis.py       Fisher z meta-analysis across runs
  FLIR_Delta_Analysis.py      Pairwise Pearson delta analysis (alternative)
  shared_utils.py             Feature computation + CCF math
  mesh_defs.json              ROI polygon definitions (all 3 camera types)
  mesh_loader.py              JSON loader with GitHub download + local cache
  editors/
    back_mesh_editor.py       GUI editor for back-of-head ROI mesh
    frontal_mesh_editor.py    GUI editor for frontal ROI mesh
    profile_mesh_editor.py    GUI editor for dual-profile ROI mesh (J = export)

docs/
  assets/                     Representative overlays + meta-analysis figures
  REPORT.md                   Full technical report with math and results

Features Extracted per ROI

Feature Definition
mean Mean pixel temperature (°C)
median Median pixel temperature
max Maximum pixel temperature
min Minimum pixel temperature
variance Sample variance (ddof=1)
energy Mean squared temperature
entropy Shannon entropy of 32-bin histogram (bits)
kurtosis Excess kurtosis (Fisher definition)
skewness Distribution skewness

npixels (ROI size) is computed but excluded from correlation analysis.


Analysis Parameters

Parameter Default Description
dt 5.0 s Resampling grid spacing
alpha 0.05 Bartlett CI and Fisher CI significance level
max_lag n // 3 Maximum CCF lag tested
top_k 9 Pairs per feature in per-feature grid plots
top_n 10 Pairs in global summary leaderboard
min_runs 1 Minimum runs for meta-analysis inclusion

Dependencies

  • numpy, scipy, matplotlib
  • opencv-python, Pillow
  • mediapipe (frontal extraction)
  • ultralytics (YOLOv8, back/dual extraction)
  • flyr (FLIR radiometric JPEG parsing)

Data Availability

Raw recordings, extracted pixel data, and analysis outputs are archived on Zenodo:

DOI: 10.5281/zenodo.19700602

The deposit contains three archives:

  • Experiments.zip — raw FLIR radiometric JPEGs, one folder per session
  • Processed_Experiments.zip — extracted pixel arrays (.npz), session metadata, and ROI overlay images
  • Calc_Experiments.zip — per-session statistics CSVs, resampled time-series, CCF tables, and plots

See Also

docs/REPORT.md — full technical report covering coordinate geometry, feature math, statistical methods, and per-experiment results with figures.

Metadata

Release files for thermophysio 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for thermophysio 0.1.1
File Size Uploaded
thermophysio-0.1.1.tar.gz 107.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for thermophysio 0.1.1
File Interpreter ABI Platform
thermophysio-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 221.9 kB

Release files / thermophysio-0.1.1.tar.gz

Download URL thermophysio-0.1.1.tar.gz
Size 107.1 kB
Tags Source
SHA-256 checksum
How to use checksums
40cdd9741c1a6bc53d097643893be7a0b204ca6de071f585316e2e1a724140b3
BLAKE2b-256 checksum
How to use checksums
683b23403c9cae0b4b07f68db4d3dbf6fb68798c40adc2cef55d9ce675a4ce0d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 24, 2026.

Transparency log

Release files / thermophysio-0.1.1-py3-none-any.whl

Download URL thermophysio-0.1.1-py3-none-any.whl
Size 114.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6be327e4d0b7ef48423c6bc409f0559c27f1eba11e91c357090e2de082ad0632
BLAKE2b-256 checksum
How to use checksums
f9e75f8709b3b6550d072ed5ab14ff48b9b9116e54b0a59902f3c5ae628f623c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page