FLIR thermal imaging analysis pipeline for psychophysiology research
Project description
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:
The deposit contains three archives:
Experiments.zip— raw FLIR radiometric JPEGs, one folder per sessionProcessed_Experiments.zip— extracted pixel arrays (.npz), session metadata, and ROI overlay imagesCalc_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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file thermophysio-0.1.0.tar.gz.
File metadata
- Download URL: thermophysio-0.1.0.tar.gz
- Upload date:
- Size: 107.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7eaf3f90a6157f3d362cc52d57b04dcb81d397ce5662c0c3ef310564202a910a
|
|
| MD5 |
8829815c2de8f7d073c459f275aace17
|
|
| BLAKE2b-256 |
aa267e751c2582341349e86529f6a74680d7278c85cbdc1e66904ca108362a11
|
File details
Details for the file thermophysio-0.1.0-py3-none-any.whl.
File metadata
- Download URL: thermophysio-0.1.0-py3-none-any.whl
- Upload date:
- Size: 114.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18370a4238fe1c5a66475378a049eb1599fbb141fed0ad3fccb250fdbc37e8c0
|
|
| MD5 |
a4f8f1359b1d9f6b60baa839338f1828
|
|
| BLAKE2b-256 |
e88d6169a36bc2782d1c215c2f106ccc0a89df0e62487eac313fb76ce2266592
|