Skip to main content

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:

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.

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

thermophysio-0.1.1.tar.gz (107.1 kB view details)

Uploaded Source

Built Distribution

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

thermophysio-0.1.1-py3-none-any.whl (114.8 kB view details)

Uploaded Python 3

File details

Details for the file thermophysio-0.1.1.tar.gz.

File metadata

  • Download URL: thermophysio-0.1.1.tar.gz
  • Upload date:
  • Size: 107.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for thermophysio-0.1.1.tar.gz
Algorithm Hash digest
SHA256 40cdd9741c1a6bc53d097643893be7a0b204ca6de071f585316e2e1a724140b3
MD5 223e416e8c94ee9681dcc9d8f1fab051
BLAKE2b-256 683b23403c9cae0b4b07f68db4d3dbf6fb68798c40adc2cef55d9ce675a4ce0d

See more details on using hashes here.

Provenance

The following attestation bundles were made for thermophysio-0.1.1.tar.gz:

Publisher: publish.yml on RauwP/thermophysio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file thermophysio-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: thermophysio-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 114.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for thermophysio-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6be327e4d0b7ef48423c6bc409f0559c27f1eba11e91c357090e2de082ad0632
MD5 786c5bc849cef3b601ad8ce50fb29f5f
BLAKE2b-256 f9e75f8709b3b6550d072ed5ab14ff48b9b9116e54b0a59902f3c5ae628f623c

See more details on using hashes here.

Provenance

The following attestation bundles were made for thermophysio-0.1.1-py3-none-any.whl:

Publisher: publish.yml on RauwP/thermophysio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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