FlowStudio — Guida Estesa (Italiano)

Scopo di questo documento. Questa guida spiega come nascono le misure e la matematica che c’è dietro, partendo dalle basi. Descrive i comandi e i parametri utilizzabili nell’applicazione, senza dare nulla per scontato.
Importante. I numeri prodotti da FlowStudio dipendono in modo critico dalla qualità del video (fuoco, stabilità della luce, compressione, frame rate, inquadratura). Se usi i risultati per ricerca o per report clinici, valida la procedura su riferimenti noti e mantieni costanti le condizioni di acquisizione.

Indice


0) Architettura e pipeline

FlowStudio è organizzato come una pipeline in tempo reale: ad ogni nuovo frame aggiorna il campo di moto, i segnali per-cella, le mappe di frequenza, gli spettri e (opzionalmente) l’oscillatore di regione (“blob”). La GUI imposta i parametri e visualizza i risultati; la catena di misura è la stessa sia con sorgente live (camera) sia con file video.

0.1 Pipeline di elaborazione (dal frame ai numeri)

Sorgente (Camera / File video)
   ↓ frame @ FPS        →   dt = 1/FPS
Preprocessing (opzionale: Blur / CLAHE)
   ↓
Optical Flow (frame t → t+1)                        [vedi §6]
   ↓
Affidabilità / Maschera (photoErr, FB, gradiente, MAD…)   [vedi §7]
   ↓
Riduzione a griglia (aggregazione celle + EMA + stabilità) [vedi §8]
   ↓
Segnale per-cella x[n] (modulo / U / V) + decimazione D  →  fs_eff = FPS/D   [vedi §9–§10]
   ↓
Rapid Oscillation Analyzer (passa-banda + autocorrelazione → f0, corr, rms, stable)   [vedi §10]
   ↓
Mappe & Overlay (f0/corr/rms/stable → overlay a colori + mappe debug)                 [vedi §11]
   ↓
Diagnostica Entropia (H(t), mappa H_local, proxy Ṡ)                                       [vedi §12]
   ↓
Aggregazione & decisioni
   ├─ Spettro / Waterfall (istogramma su celle attive)                                [vedi §13]
   ├─ Oscillatore blob (Hz(t), Coh(t) su celle stabili)                                [vedi §11.2]
   └─ Detector (baseline/cambi) → Event recorder → export CSV / riassunti Before–After [vedi §14–§18]

0.2 Come si connettono i blocchi nella GUI

0.3 Resync vs Reset (cosa viene azzerato)

0.4 Barra di stato, timecode e log


1) Cosa misura FlowStudio

FlowStudio analizza una sequenza di immagini (camera o file video) per misurare micro-movimenti e, soprattutto, oscillazioni rapide (ad esempio tremore, vibrazioni, micromovimenti periodici) all’interno di una regione selezionata. L’idea chiave è:

  1. Stimare un vettore di spostamento tra frame consecutivi (optical flow).
  2. Trasformare il moto nel tempo in un segnale per piccole aree (celle).
  3. Stimare la frequenza dominante del segnale con una finestra corta scorrevole.
  4. Aggregare le frequenze su tutta la regione per costruire uno spettro e rilevare cambiamenti/eventi.

FlowStudio produce sia informazioni visive (overlay, vettori, mappe, spettro/waterfall) sia numeriche (statistiche, eventi, riassunti Before/After).

1.1 “Moto” in una frase

Tra il frame t e il frame t+1 FlowStudio stima un vettore v(x,y) = (u, v) per ogni pixel (o un sottoinsieme denso), che significa “questo punto si è spostato di u pixel in orizzontale e v pixel in verticale”.

1.2 “Oscillazione” in una frase

Se un punto si muove avanti–indietro in modo periodico, la sua componente di spostamento nel tempo assomiglia a un’onda. La frequenza è “quanti cicli al secondo” (Hz).


2) Video, tempo, campionamento, unità

2.1 Frame, FPS e passo temporale

Un video è una sequenza di frame. Se l’acquisizione è a FPS frame al secondo, allora l’intervallo temporale tra due frame è:

dt = 1 / FPS   (secondi)

Esempio: 200 FPS ⇒ dt = 0.005 s (5 ms).

2.2 Campionamento e limite di Nyquist (perché gli FPS contano)

Per misurare un’oscillazione di frequenza f devi campionare abbastanza velocemente. La regola base è il limite di Nyquist: serve circa FPS > 2·f. In pratica è meglio avere più margine (ad esempio 5×–10×) per una stima robusta.

2.3 Unità in pixel e unità fisiche (µm)

Le grandezze interne sono in pixel per frame (px/frame). Per convertirle in unità fisiche devi fornire una calibrazione:

um_per_px = micrometri rappresentati da 1 pixel

Le velocità diventano:

velocita_um_s = (velocita_px_frame) * FPS * um_per_px

Nota: se non conosci la calibrazione puoi comunque confrontare valori relativi (prima/dopo, condizioni diverse), ma non puoi riportare µm/s in modo affidabile.


3) Flusso di lavoro consigliato

  1. Seleziona la sorgente: camera o file video.
  2. Se usi la camera: scegli Select Camera e Camera Resolution; in Camera Settings prova a disattivare auto-esposizione/auto-gain per evitare flicker.
  3. Start per avviare l’analisi.
  4. Seleziona una ROI (opzionale ma consigliata): isola l’area d’interesse e riduci rumore.
  5. Controlla fuoco e illuminazione: evita blur, saturazione e sfarfallio.
  6. Regola i gate principali nel pannello Main:
  7. Osserva spettro/waterfall e mappe per confermare che la banda misurata sia sensata.
  8. (Opzionale) Abilita Session recording (SQLite) (menu File) per salvare la sessione in un file .sqlite con metriche per-frame e (se richiesto) vettori di flow su griglia. Vedi §15.5.
  9. (Opzionale) Abilita Event recorder per salvare sequenze quando c’è un trigger.
  10. (Opzionale) Clinico Before/After: registra due segmenti, imposta calibrazione, genera report.
Suggerimento. Dopo variazioni importanti dei parametri usa Resync per azzerare lo storico e ripartire pulito.

4) Comandi e scorciatoie

4.1 Comandi principali

ComandoSignificato
StartAvvia l’elaborazione sulla sorgente selezionata (camera o file).
StopFerma l’elaborazione e rilascia la sorgente.
Open Video…Apre un file video.
Open RecentRiapre uno degli ultimi file video usati (fino a 16).
Restart VideoRiavvia riproduzione/elaborazione dall’inizio del file corrente.
Pause / ResumeMette in pausa/riprende l’elaborazione. Alla ripresa avviene una risincronizzazione.
ResyncPulisce lo stato a breve termine e risincronizza la catena (utile dopo ROI/seek).
ResetReset completo degli stati interni e contatori (analisi, istogrammi, baseline del detector).
Clear ROIDisabilita la ROI e torna al full-frame.
Fit docksRipristina la disposizione predefinita dei pannelli.
Select Camera...Seleziona il dispositivo camera UVC/DirectShow (Windows). Utile con più camere collegate.
Camera Resolution...Seleziona risoluzione/formato della camera. Consigliato prima di Start (soprattutto su USB2/USB3) per stabilizzare FPS e qualità.
Camera Settings...Apre le proprietà del driver (pagine UVC/DirectShow, Windows). Serve per disattivare auto-esposizione/auto-gain quando possibile.
Video hardcopyRegistra l’intera finestra (menu + dock + status) in un file video. Utile per documentare sessioni e parametri “così come visti”.
Session recording (SQLite)...Crea/aggiorna un file SQLite (.sqlite) con una riga per frame (tabella frames) e un record per ogni “run”/segmento (tabella runs). Consiglio: abilita la registrazione e poi Restart Video / Start camera per un take pulito. [vedi §15.5]
Record grid flow (heavy)Se attivo, registra anche i vettori di flow per-cella (tabella grid_flow). Può aumentare molto carico e dimensione del DB: usa hop più alto e/o griglia meno densa.
Verify session DB integrity...Esegue PRAGMA integrity_check e statistiche base sul file di sessione selezionato, stampando il risultato nel Log. Utile per confermare che la registrazione sia completa.
AI Request...Crea un pacchetto (report + dati strutturati) per valutazione esterna: PDF/JSON/CSV/immagini. Non modifica l’analisi, è solo export.
HelpApre questa guida.

4.2 Toggle di visualizzazione

4.3 Scorciatoie da tastiera

Le scorciatoie servono per tarare rapidamente durante l’osservazione:


5) ROI (Regione di Interesse)

La ROI è un rettangolo dell’immagine su cui viene eseguita l’analisi. Tutto (moto, frequenza, spettro) è calcolato solo dentro la ROI.

5.1 Perché la ROI è importante

5.2 Quando usare Resync

Cambiare ROI cambia geometria e buffer storici. Dopo modifiche alla ROI (o dopo uno spostamento/seek nel file), usa Resync per evitare di mescolare dati non compatibili.


6) Stima del moto (Optical Flow Detector)

FlowStudio stima lo spostamento tra frame consecutivi in scala di grigi. Il modello classico è la costanza di luminosità: un punto mantiene circa la stessa intensità mentre si muove.

6.1 L’idea dell’optical flow

Sia I(x,y,t) l’intensità. Se un punto si sposta di (u,v) tra due frame:

I(x, y, t) ≈ I(x + u, y + v, t + dt)

Un algoritmo di optical flow trova (u,v) che soddisfa al meglio questa relazione su intorni e su più scale. FlowStudio usa un metodo denso multi-scala adatto a moti piccoli/medi.

6.2 Preprocessing (opzionale)

Nota pratica. Evita preprocessing eccessivo: se distruggi la texture, il moto diventa ambiguo e l’affidabilità cala.

7) Affidabilità, maschera e qualità

Non tutti i vettori di moto sono affidabili. FlowStudio calcola una maschera e una confidenza per evitare che zone inaffidabili contribuiscano alla stima di frequenza.

7.1 Indizi usati per la confidenza

  1. Errore fotometrico: dopo aver “warpato” il frame 1 usando il flow stimato, lo confronta con il frame 2.
    photoErr(x,y) = | I2(x,y) − warp(I1, flow12)(x,y) |
    Errore basso ⇒ il moto spiega bene i cambiamenti di intensità.
  2. Coerenza forward–backward: stima flow 1→2 e 2→1; un moto coerente deve “tornare indietro”:
    fbErr ≈ | flow12(p) + flow21(p + flow12(p)) |
    Errore alto ⇒ occlusioni, blur, mismatch.
  3. Deviazione locale: confronta il vettore con la mediana locale. Un vettore molto diverso dai vicini è spesso un outlier.
  4. Gate di texture (gradiente): in aree piatte (gradiente basso) il moto è mal definito. Si impone una soglia minima sul modulo del gradiente per evitare “flow sul rumore”.
  5. Dispersione di cella (MAD): se dentro una cella i vettori sono troppo dispersi, la cella è instabile. MAD (Median Absolute Deviation) è una misura robusta della dispersione.

7.2 Dalla confidenza alla maschera

Ogni indizio ha una soglia (Tphoto, Tfb, Tdev, Tgrad, Tmad). Un pixel passa la maschera se soddisfa i criteri abilitati. Dopo la maschera, una pulizia morfologica opzionale rimuove puntini isolati.

7.3 Numero di qualità (inlier ratio)

Una qualità globale semplice è la frazione di pixel/celle che passano i controlli di affidabilità. Nei riassunti viene riportata come quality (%).


8) Riduzione a griglia e stabilizzazione

8.1 Perché ridurre a griglia?

Il flow denso produce un vettore per pixel. Analizzare la frequenza per pixel sarebbe troppo pesante e rumoroso. FlowStudio aggrega quindi i vettori in celle quadrate di lato Cell size.

8.2 Aggregazione per cella (statistiche robuste)

Dentro ogni cella si usano solo i pixel affidabili (maschera). Il vettore di cella è una stima robusta:

Una cella è valida solo se contiene almeno Min samples pixel affidabili.

8.3 Smussamento temporale (EMA) e clamp del salto

I vettori di cella oscillano per rumore. Una media mobile esponenziale (EMA) li smussa:

v_smooth[t] = α · v_new[t] + (1 − α) · v_smooth[t−1]

Il parametro Max jump limita cambi improvvisi non realistici: se |v_new − v_prev| è troppo grande l’aggiornamento viene respinto o limitato.

8.4 Persistenza (stabilità su più frame)

Per stimare oscillazioni servono celle con segnale coerente nel tempo. La persistenza mantiene un contatore stable per cella: cresce quando il moto cambia poco (entro epsilon) e cala quando diventa incoerente o mancante.


9) Dal moto a un segnale

Dopo la griglia, hai un vettore per cella e per frame. Lo trasformi in un segnale 1D x[n]. FlowStudio offre tre modalità:

Perché usare una componente e non la magnitudine? Una componente con segno conserva la direzione (avanti–indietro diventa un’oscillazione pulita attorno a zero), mentre la magnitudine può “raddrizzare” il segnale e introdurre armoniche.


10) Rapid Oscillation Analyzer (frequenza per cella)

È il motore centrale della frequenza. Per ogni cella FlowStudio mantiene un buffer corto e stima la frequenza dominante.

10.1 Frequenza di campionamento effettiva e decimazione

Con FPS alti (es. 200 FPS) puoi decimare di un fattore D: si fa la media di D frame per ottenere un campione. Questo riduce rumore e costo computazionale.

fs_eff = FPS / D

Tutta la parte di frequenza usa fs_eff.

10.2 Filtro passa-banda semplice (HP + LP del 1° ordine)

Il moto grezzo contiene drift lento (postura, drift camera) e rumore veloce. FlowStudio usa un passa-banda costruito con:

Sono filtri standard del 1° ordine in tempo discreto:

high-pass:   y[n] = a · ( y[n−1] + x[n] − x[n−1] )
low-pass:    y[n] = y[n−1] + b · ( x[n] − y[n−1] )

I tagli sono in Hz e vengono interpretati con fs_eff.

10.3 Finestra scorrevole: N e Hop

Ogni cella ha un buffer circolare di N campioni. La durata temporale coperta è:

durata_finestra = N / fs_eff  (secondi)

L’analizzatore aggiorna ogni Hop campioni, quindi la velocità di aggiornamento è circa:

aggiornamenti_al_secondo ≈ fs_eff / Hop

N piccolo ⇒ risposta rapida ma risoluzione peggiore; N grande ⇒ stima più stabile ma più lenta.

10.4 Stima di frequenza con autocorrelazione normalizzata

Per trovare periodicità, FlowStudio calcola l’autocorrelazione normalizzata. Prima si sottrae la media (oscillazione centrata a zero). Poi, per ogni lag L:

corr(L) =  Σ_{i=0..M−1} x[i]·x[i+L]  /  sqrt( Σ x[i]^2 · Σ x[i+L]^2 )
dove M = N − L

È un coefficiente di correlazione tra il segnale e una copia ritardata. È circa in [−1, +1]. FlowStudio usa il picco positivo come misura di periodicità.

10.5 Ricerca solo in una banda di frequenza

La ricerca è limitata alla banda [fMin, fMax]. Le frequenze corrispondono a lag:

L ≈ fs_eff / f
lagMin = floor(fs_eff / fMax)
lagMax = ceil (fs_eff / fMin)

Si sceglie il lag con corr(L) massimo nell’intervallo [lagMin, lagMax].

10.6 Gate sull’energia RMS

Prima di fidarsi dei picchi corr, FlowStudio controlla che il segnale abbia energia sufficiente:

RMS = sqrt( mean( x[i]^2 ) )

Se RMS è sotto RMS thr, la cella è inattiva (nessuna oscillazione significativa).

10.7 Interpolazione sub-lag (frequenza più precisa)

Il lag è discreto, ma il periodo reale può stare tra due lag. FlowStudio raffina il lag migliore con una piccola interpolazione parabolica usando corr(L−1), corr(L), corr(L+1). Poi:

f0 = fs_eff / lagFrac

10.8 Persistenza della frequenza (contatore stable)

Anche dopo gating, la frequenza può saltare per rumore. FlowStudio mantiene un contatore per cella: se |f0 − f0_precedente| ≤ freqTol, il contatore aumenta; altrimenti riparte. Questo valore “stable” è un’ulteriore misura di affidabilità.


11) Mappe: f0 / corr / rms / stable

Dopo l’analisi di tutte le celle, FlowStudio costruisce mappe su griglia:

11.1 Overlay: colore + trasparenza

L’overlay fonde:

La trasparenza (alpha) deriva da corr, rms e stable, con le soglie principali:

se corr < CorrThr o rms < RmsThr → alpha = 0

cc = (corr − CorrThr) / (1 − CorrThr)   limitato a [0,1]
rr = (rms  − RmsThr ) / (3·RmsThr)      limitato a [0,1]
ss = min(1, stable / stableNeed)

alpha = alphaBase · cc · rr · ss · AlphaBoost   limitato a [0,1]

La vista finale:

output = (1−alpha)·(BW·BWgain) + alpha·(COLOR·ColorGain)

Quindi: oscillazioni più forti, più periodiche e più stabili diventano più visibili.


11.2 Oscillatore del blob (Hz + Coh a livello di regione)

Oltre alla frequenza per cella, FlowStudio può stimare anche un oscillatore equivalente dell’intera ROI/blob: una traccia unica Hz(t) più un numero di coerenza Coh(t) che indica quanto la regione si comporta come “un solo oscillatore” (coerenza alta) rispetto a una somma di parti sfasate/rumore (coerenza bassa).

Dove lo trovi nella GUI. Il grafico temporale è nella tab Oscillator Plot (tabificata insieme a Spettro/Waterfall e Log). Le immagini di debug sono nel dock F0 Map → sub-tab Oscillator (Amp/Phase/Contrib/Mask). Per risparmiare CPU, l’intero blocco resta spento se Enable blob oscillator (heavy) non è selezionato.

11.2.1 Selezione delle celle stabili (gate “stable-only”)

L’oscillatore del blob usa solo le celle già considerate affidabili dal Rapid Oscillation Analyzer. Per ogni cella i sono disponibili: corri (periodicità), rmsi (energia) e stablei (persistenza). L’insieme attivo è:

S = { i | corr_i ≥ CorrThr  e  rms_i ≥ RmsThr  e  stable_i ≥ stableNeed }

Se |S| è troppo piccolo, l’output dell’oscillatore viene marcato come non valido per quell’aggiornamento (mancano celle stabili sufficienti per una stima robusta).

11.2.2 Da molti segnali di cella a un segnale di regione

Per ogni cella in S, FlowStudio mantiene già un segnale temporale passa-banda xi[n] (gli stessi filtri/decimazione usati dalla stima per cella; vedi Sezioni 10.1–10.3). Il segnale equivalente di regione è la media:

y[n] = (1 / |S|) · Σ_{i∈S} x_i[n]

Intuizione: la media riduce il rumore non correlato e mette in evidenza il moto comune alle celle stabili.

11.2.3 Frequenza dominante della regione (picco FFT/DFT in banda)

Ad ogni aggiornamento (ogni Hop campioni), FlowStudio calcola la trasformata discreta di Fourier (DFT) di y[n] sulla finestra corrente:

Y[k] = Σ_{n=0..N−1} y[n] · exp( −j · 2π · k · n / N )
f_k  = k · fs_eff / N

Il bin di massimo viene cercato solo nella banda [fMin, fMax] (la stessa banda usata per f0 per cella):

kMin = ceil( fMin · N / fs_eff )
kMax = floor( fMax · N / fs_eff )
k*   = argmax_{k ∈ [kMin..kMax]} |Y[k]|
Hz   = f_{k*}
Amp  = |Y[k*]|            (ampiezza relativa)

Amp è una magnitudine spettrale relativa della regione. Se servono unità fisiche (µm/s, µm), va combinata con calibrazione (µm/px) e FPS.

11.2.4 Coerenza (Coh): quanto la regione è “un solo oscillatore”

Una volta noto il bin di picco k*, ogni cella stabile contribuisce con un coefficiente complesso a quella frequenza:

X_i = Σ_{n=0..N−1} x_i[n] · exp( −j · 2π · k* · n / N )

La coerenza è un rapporto di allineamento di fase (0..1):

Coh = | Σ_{i∈S} X_i |  /  Σ_{i∈S} |X_i|

11.2.5 Mappe di debug (opzionali, più pesanti)

Se è attivo Compute debug maps, FlowStudio costruisce mappe per cella alla frequenza di picco k*:

11.2.6 Nota implementativa (ricerca del picco FFT vs Goertzel su un singolo bin)

La ricerca del picco usa una FFT/DFT sul segnale di regione y[n] per trovare il bin migliore k* nella banda [fMin, fMax]. Una volta noto k*, i coefficienti complessi per-cella Xi a quel solo bin possono essere calcolati in due modi equivalenti:

La DFT su un bin è:

X_i(k*) = Σ_{n=0..N−1} x_i[n] · exp( −j · ω · n ),   con  ω = 2π · k* / N

L’algoritmo di Goertzel calcola lo stesso valore tramite una ricorrenza del 2° ordine:

s[n] = x[n] + 2·cos(ω)·s[n−1] − s[n−2]     con s[−1]=s[−2]=0
X(k*) = s[N−1] − exp(−j·ω)·s[N−2]

In FlowStudio la FFT su y[n] serve a scegliere k* (Hz). Lo stesso k* viene poi usato per calcolare Coh e (opzionalmente) le mappe debug tramite i coefficienti Xi sul singolo bin. La matematica è equivalente alla FFT completa, con costo CPU più basso.

Consigli pratici. Se Hz è instabile o Coh resta bassa, prova: ROI più piccola, aumentare CorrThr/RmsThr/stableNeed, o restringere la banda [fMin, fMax]. Coh bassa spesso significa più sorgenti di oscillazione dentro la ROI o un forte gradiente di fase.


12) Entropia (H globale, mappe spaziali, e proxy di produzione entropica)

Questo pannello aggiunge una famiglia di misure basate su entropia, pensate come diagnostica di quanto l’attività oscillatoria è concentrata oppure distribuita in frequenza e nello spazio. In FlowStudio “entropia” è usata nel senso di Shannon (entropia dell’informazione) applicata a distribuzioni costruite a partire dalle mappe già disponibili (f0, corr, rms, stable) e dall’istogramma di frequenza.

Terminologia. In elaborazione di segnali l’entropia di Shannon aumenta quando una distribuzione diventa più “spalmata”/imprevedibile. In termodinamica la produzione di entropia è legata alla potenza dissipata: Ṡ ≈ Pdiss/T. FlowStudio fornisce entrambe le cose:

12.1 Entropia globale H(t) dall’istogramma di frequenza

Ad ogni aggiornamento FlowStudio costruisce già un istogramma di frequenza contando quante celle hanno una frequenza dominante f0 valida (solo celle che passano gli stessi gate di “oscillazione valida”: banda + CorrThr + RmsThr + StableNeed). Sia l’istogramma composto da K bin e conteggi ck. Si normalizza in probabilità:

p_k = c_k / Σ c_k
H   = − Σ p_k · log(p_k)          (entropia di Shannon; base e)
H01 = H / log(K)                  (normalizzata in 0..1)
Interpretazione. Una H01 che cresce spesso indica l’uscita da un regime periodico pulito verso un regime con più modi, intermittenze, impatti, o non-linearità forti. Viceversa, una H01 che scende può indicare “locking” su un modo dominante.

12.2 Mappa di entropia spaziale Hlocal(x,y): quanto è “mista” la zona attorno

Mentre H(t) è un riassunto a livello di regione, Hlocal(x,y) è una mappa. Per ogni cella (x,y) FlowStudio considera un intorno quadrato di raggio R (in celle di griglia) e costruisce un piccolo istogramma dei valori f0 nell’intorno, dopo quantizzazione in K bin (parametro “bins”). Poi calcola l’entropia di Shannon (normalizzata 0..1) di quella distribuzione locale.

Formalmente, per un intorno N(x,y):

p_k(x,y) = conteggio celle in N(x,y) con f0 nel bin k  /  totale celle valide in N(x,y)
H_local(x,y)  = − Σ p_k(x,y) · log(p_k(x,y))
H_local01(x,y)= H_local(x,y) / log(K)
Importante. Hlocal ha senso solo dove l’intorno contiene abbastanza celle valide. Se ci sono pochi campioni validi, la cella viene marcata come “no-data” (tipicamente nero). Per ridurre “falsa entropia” dovuta a celle inaffidabili, lascia abilitato Use Oscillation mask.

12.3 Mappa Power proxy e proxy di Ṡ(t)

Una produzione entropica termodinamica, in prima approssimazione, sarebbe:

Ṡ ≈ P_diss / T

Tuttavia, dalle sole immagini spesso non hai accesso diretto alla potenza dissipata calibrata. FlowStudio fornisce quindi un proxy che correla con “quanta attività oscillatoria c’è” e che è visualizzabile come mappa. Un default pratico è:

powerProxy(x,y) = rms(x,y)^2 · corr(x,y)     (solo su celle valide/gated)
P_proxy(t)      = Σ powerProxy(x,y)
Sdot_proxy(t)   = powerScale · P_proxy(t) / T

Note. rms è calcolato dopo passa-banda; corr è il picco di autocorrelazione. Il fattore powerScale è una scala utente per rendere leggibile il plot. Se disponi di un modello meccanico calibrato (massa, rigidezza, smorzamento) o una stima diretta di Pdiss, puoi sostituire il proxy con l’espressione fisica mantenendo identica la visualizzazione.

12.4 Parametri GUI e prestazioni

Prestazioni. H(t) è leggero (un istogramma per aggiornamento). Hlocal(x,y) è più pesante perché costruisce istogrammi locali per cella; usalo quando serve o con R più piccolo.

12.5 Export

12.6 Errori tipici e consigli pratici


12.5) Metric Space (metrica delle metriche)

Metric Space è una vista 3D che trasforma l’andamento temporale di molte metriche (frequenze, entropia, qualità, trigger, ecc.) in una traiettoria nello spazio. Ogni punto della curva rappresenta un campione nel tempo (uno ogni Hop frames) e viene colorato secondo la metrica scelta. L’obiettivo non è “misurare una nuova grandezza”, ma vedere in un colpo d’occhio lo stato del sistema: regimi stabili, transizioni, cluster e differenze Before/After.

12.5.1 Da dove arrivano i punti

FlowStudio costruisce un vettore di caratteristiche a 16 dimensioni (normalizzato in modo robusto con mediana e MAD su una finestra temporale) che include, tra le altre, queste grandezze:

Quel vettore viene poi “compresso” in 3D con un embedding:

Interpretazione pratica. Se la traiettoria “sta su un tubo” o forma un cluster compatto, lo stato è stabile. Se vedi salti netti o ramificazioni, è spesso un cambiamento reale (movimento, illuminazione, cambio ROI) oppure un evento/trigger.

12.5.2 Parametri principali (Controls → Metric Space)

ParametroCosa faNote pratiche
EnableAttiva la generazione della traiettoria.Se disattivo, la vista resta ferma.
Hop framesDecimazione temporale: 1 punto ogni N frame.Aumenta per alleggerire (es. 3–10).
Window (sec)Finestra usata per normalizzazione robusta e (se non congelata) per aggiornare la PCA.Più lunga = base più stabile, ma meno reattiva.
EmbedPCA oppure LMDS.LMDS è più costoso; usa landmark moderati.
Freeze basisBlocca normalizzazione + base quando c’è abbastanza storia.Consigliato per confronti e per evitare “salti” geometrici.
View modeCurva 3D o asse tempo (z=t), con resa: line/points, ribbon, tube, density.Ribbon/tube aiutano la lettura; density mostra un “attrattore”.
ColorColora i punti per Time, Peak Hz, Entropy H, Osc Hz, Quality, Global speed, Osc Coh.Ottimo per capire “che cosa cambia” lungo la traiettoria.
Max pointsLimite alla storia (numero massimo di punti mantenuti).Evita crescita infinita; utile per sessioni lunghe.
Landmarks (LMDS)Numero di landmark per LMDS.256 è spesso un buon compromesso.
ResetAzzera la traiettoria e ricomincia.Usalo dopo cambi di sorgente o di condizioni.

12.5.3 Controlli del viewer (mouse)

12.5.4 Modalità Density + Iso (firma 3D)

In modalità Density cloud i punti vengono voxelizzati in una griglia 3D (bins^3) e mostrati come una nuvola pesata. L’overlay Iso disegna un’isorisuperficie delle zone più dense: è una specie di firma della traiettoria.

12.5.5 Export

Nota su prestazioni. LMDS e Density/Iso sono le modalità più costose. Se vedi rallentamenti: (a) aumenta Hop frames, (b) riduci Max points o Density bins, (c) usa PCA e/o congela la base.

13) Istogramma di frequenza, spettro e waterfall

12.1 Dalle frequenze per cella all’istogramma

Ogni cella che passa il gating contribuisce a un bin dell’istogramma. Il bin rappresenta una frequenza, usando una scala:

bin = round( f0 · scale )    (scale = bin per Hz)

Si accumulano solo le frequenze in [Hist fMin, Hist fMax].

12.2 Modalità di pesatura

La cella può contribuire con un semplice conteggio o con un peso:

La pesatura enfatizza oscillazioni forti/periodiche e riduce quelle deboli/rumorose.

12.3 Frequenza di picco

Il bin massimo definisce la frequenza dominante del frame:

peakHz = peakBin / scale

12.4 Waterfall

La waterfall è una visualizzazione tempo–frequenza: ogni riga è un istogramma, e le righe scorrono nel tempo. È utilissima per capire se la frequenza è stabile, deriva o è intermittente.


14) Baseline e rivelatore di cambiamento di frequenza

Il detector genera un trigger quando la frequenza dominante cambia oltre la variabilità normale. Mantiene una baseline (media mu e varianza var) con una media mobile esponenziale (EWMA).

13.1 Baseline EWMA

mu[t]  = (1−α)·mu[t−1]  + α·f[t]
var[t] = (1−α)·var[t−1] + α·(f[t]−mu[t])^2
sigma  = sqrt(var)

α piccolo ⇒ memoria lunga (baseline lenta).

13.2 Soglia dinamica

Un cambiamento è significativo se:

|f − mu| > max( absHz, rel·mu, kSigma·sigma )

13.3 Consecutivi e cooldown

13.4 Gating

Baseline e trigger si aggiornano solo quando il frame ha abbastanza celle valide. Così la baseline non viene “sporcata” da frame senza segnale.


15) Event recorder

Quando il detector triggera, l’event recorder salva sequenze di immagini attorno all’evento:

Al momento del trigger può salvare anche snapshot diagnostiche: overlay, mappa corr, mappa f0, maschera.

15.5) Registrazione sessione (SQLite)

Oltre al salvataggio “a eventi” (Event recorder), FlowStudio può registrare una sessione di misura completa in un database SQLite. Il file risultante (.sqlite) contiene metriche per-frame (QC) e, opzionalmente, i vettori di moto su griglia.

15.5.1 Procedura operativa

  1. Apri il menu File → Session recording (SQLite)... e scegli il percorso del file .sqlite. La voce rimane spuntata (registrazione “armata”).
  2. (Opzionale) abilita File → Record grid flow (heavy) se vuoi salvare anche i vettori per-cella (grid_flow).
  3. Per iniziare un segmento pulito: usa Restart Video (file) oppure Start (camera). Alla prima frame utile FlowStudio crea automaticamente un nuovo run.
  4. Quando hai finito, disabilita Session recording (SQLite)... (oppure ferma il runtime): FlowStudio fa commit/checkpoint e chiude il DB.
Nota su WAL e dimensione del file. In modalità WAL SQLite può creare file affiancati nome.sqlite-wal e nome.sqlite-shm. Durante la registrazione il file principale .sqlite può restare relativamente piccolo: è normale. Allo stop FlowStudio esegue un checkpoint per “ripiegare” i dati nel file principale. Se devi copiare la sessione mentre stai registrando, copia anche -wal e -shm insieme al .sqlite.

15.5.2 Struttura del database

TabellaContenuto
metaChiavi/valori: schema, versione, data creazione, meta_json (JSON fornito dalla UI), source_meta_json (info sorgente).
runsUn record per segmento/run (inizio acquisizione o “restart”): contiene timestamp iniziale e snapshot dei parametri sorgente (fps, dimensioni, ecc.).
framesUna riga per frame con le principali metriche di QC: peak/baseline Hz, quality, activity, fps, drop, luminanza/blur/saturazione, ROI, ecc.
grid_flow(Opzionale) Vettori di flow su griglia: per ogni frame (eventualmente sottocampionato da hop) salva (cx,cy,u,v,conf,stable).
eventsEventi leggeri (JSON): run_start/run_end, roi_changed, ed eventuali altri marker futuri.
Prestazioni. Record grid flow (heavy) può generare molte righe (celle × frame). Se ti serve solo QC per-frame, lascialo disattivo. Se ti serve, valuta: aumentare hop, aumentare cell size, o ridurre ROI.

15.5.3 Controllo integrità dal menu

Per verificare rapidamente che il file sia sano e completo usa File → Verify session DB integrity...: FlowStudio esegue PRAGMA integrity_check; e stampa nel Log anche conteggi e range di indici (runs/frames).

15.5.4 Query utili (DB Browser / sqlite3)

-- quante righe sono state scritte
SELECT COUNT(*) FROM frames;

-- frame per run
SELECT run_id, COUNT(*) AS n
FROM frames
GROUP BY run_id
ORDER BY run_id;

-- intervallo temporale (microsecondi UTC) del run 1
SELECT MIN(t_us), MAX(t_us) FROM frames WHERE run_id=1;

-- picco medio e qualità media (run 1)
SELECT AVG(peak_hz) AS peakHz_mean, AVG(quality01) AS q_mean
FROM frames
WHERE run_id=1;


16) Esportazioni CSV

15.1 Statistics CSV

Esporta gli ultimi N campioni di:

15.2 Spectra CSV (sparse)

Esporta gli ultimi N istogrammi riportando solo i bin non zero: ogni riga contiene tempo, frame, activeCount, weightSum, bin, Hz e count. È molto più leggero quando i bin sono tanti (es. 1024).


17) Analisi “Sonata”

L’analisi Sonata è un riassunto “di sessione” del contenuto spettrale. Usa lo storico degli istogrammi per trovare le frequenze più presenti nel tempo.

16.1 Peak picking sullo spettro accumulato

Concettualmente:

  1. Somma gli istogrammi su molti frame per ottenere uno spettro globale.
  2. Smussa lo spettro con una media mobile (riduce picchi spuri).
  3. Cerca massimi locali (candidati).
  4. Seleziona i top N imponendo una separazione minima in frequenza.

Parametri:


18) Workflow Clinico Before/After e metriche

Questo workflow serve per confrontare due segmenti brevi acquisiti in condizioni simili (stessa ROI, stessa camera, stessa inquadratura). Produce un riassunto compatto e flag di qualità.

17.1 Procedura

  1. Imposta ROI e gate principali (Corr thr, RMS thr, Cell size) e attendi qualche secondo finché lo spettro si stabilizza.
  2. Inserisci il campo Case (testo libero).
  3. Inserisci la calibrazione Scale (um/px).
  4. Premi Record BEFORE, registra un segmento rappresentativo, poi Stop BEFORE.
  5. Premi Record AFTER, registra un altro segmento, poi Stop AFTER.
  6. Premi Report per generare il riassunto (e opzionalmente salvarlo/stamparlo).

17.2 Cosa viene misurato per frame

Durante la registrazione, ogni frame contribuisce con:

17.3 Conversioni in unità “utente”

Sia FPS_seg l’FPS misurato nel segmento. La conversione in µm/s è:

valore_um_s = valore_px_frame · FPS_seg · um_per_px

17.4 Metriche principali (significato)

MetricaSignificato
RMS speed (µm/s) La velocità globale per frame è |globalMotion|. RMS speed è la root-mean-square di tale velocità, convertita in µm/s. Rappresenta l’intensità complessiva del moto.
Drift (µm/min) Velocità globale media convertita in µm/min. Rappresenta drift lento o spostamento sostenuto.
Dominant frequency (Hz) Media di peakHz sul segmento. È la frequenza tipica dell’oscillazione.
Frequency stability (Hz) Deviazione standard di peakHz sul segmento. Più bassa ⇒ frequenza più stabile.
Peak amplitude (µm/s) Usa bestRms (px/frame) della best cell convertito in µm/s. È un proxy della “forza/ampiezza” dell’oscillazione.
Peak/Band ratio Media di peakToBand. Vicino a 1 ⇒ un’unica frequenza domina (picco stretto). Più basso ⇒ spettro più largo / frequenze miste.
Events/min Quante volte il detector di cambiamento di frequenza ha triggerato nel segmento, normalizzato al minuto.
Micro-activity (µm/s) Media del moto residuo dopo aver rimosso la traslazione globale della ROI. Misura micromovimento locale “interno” più che drift dell’intera ROI.
Active area (%) Frazione di campioni residui sopra una soglia (~0.5 px/frame), media sul segmento, in percentuale.
Quality (%) Media dell’inlier ratio (quota di moto affidabile) in percentuale. Qualità bassa ⇒ misura probabilmente non interpretabile.

17.5 Metriche avanzate sul tremore

17.6 Eventi tipo “jerk” (severità/durata/duty cycle)

Oltre al detector principale, FlowStudio caratterizza periodi “jerk-like” usando statistiche della velocità globale: stima media e deviazione standard “running”, poi apre un evento quando la velocità supera media + 3·std, e lo chiude quando resta sotto media + 2·std per alcuni frame (isteresi).

Da questi eventi ricava:

17.7 Metriche di validazione e flag di qualità

Durante la registrazione FlowStudio misura anche:

Viene generato un flag semplice:


19) Interpretazione e troubleshooting

18.1 “Vedo i vettori ma la frequenza è 0 Hz”

18.2 “Lo spettro è molto rumoroso / troppi picchi”

18.3 “La frequenza salta continuamente”

18.4 “Quality è bassa”

18.5 Come interpretare Coh (coerenza) nell’Oscillatore del blob

Coh è una metrica di allineamento di fase:

Coh = | Σ_{i∈S} X_i |  /  Σ_{i∈S} |X_i|      (0..1)
Workflow di debug con Coh bassa. Prima verifica Mask e il numero di celle attive (|S|). Poi osserva Phase e Contrib per distinguere “controfase a due lobi” da “fase casuale”. Se Coh sale molto riducendo la ROI, probabilmente la ROI conteneva più oscillatori.

20) Legenda: termini e acronimi

Acronimo / termineSignificato in FlowStudio
ROIRegione di Interesse: rettangolo in cui gira l’analisi (fuori ROI viene ignorato).
FPSFrame per secondo (frequenza di campionamento del flusso video).
dtIntervallo tra frame: dt = 1/FPS.
NyquistRegola di campionamento: la frequenza massima misurabile è circa FPS/2 (meglio avere margine nella pratica).
Optical flowStima dello spostamento tra frame consecutivi; produce un vettore (u,v) per pixel o per regione.
(u,v)Componenti orizzontale/verticale dello spostamento, tipicamente in px/frame.
px/framePixel per frame: unità interna del moto (prima della conversione in unità fisiche).
um_per_pxCalibrazione: micrometri per pixel (µm/px). Permette unità fisiche (µm, µm/s).
Maschera / inlierInsieme di pixel/celle affidabili che passano i controlli e contribuiscono alle stime.
photoErrErrore fotometrico dopo warp; basso ⇒ il flow spiega bene i cambiamenti d’intensità.
FB / fbErrErrore di coerenza forward–backward; alto ⇒ occlusioni/blur/mismatch.
MADMedian Absolute Deviation: misura robusta della dispersione usata per stabilità/outlier a livello di cella.
EMAExponential Moving Average: smussamento temporale dei vettori/segnali di cella.
Decimazione (D)Media di D frame/campioni consecutivi per ridurre rumore e costo CPU.
fs_effFrequenza di campionamento effettiva dopo decimazione: fs_eff = FPS/D.
NLunghezza finestra (numero di campioni) usata per stimare la frequenza.
HopPasso di aggiornamento (in campioni) tra analisi successive della finestra.
Banda [fMin,fMax]Intervallo di ricerca in frequenza (Hz) usato dall’analizzatore (e, opzionalmente, da altri blocchi).
HP / LPFiltri passa-alto / passa-basso usati per costruire un passa-banda (tagli: hpCut / lpCut).
RMSRoot Mean Square: energia del segnale filtrato (gate di attività/energia).
Corr / corr(L)Picco di autocorrelazione normalizzata; “score di periodicità” (gate e trasparenza alpha).
CorrThrSoglia di correlazione: periodicità minima per accettare una cella.
f0Frequenza dominante per-cella (Hz). 0 = “non valida”.
stable / stableNeedContatore di persistenza e relativa soglia: per quanto tempo la cella mantiene f0 coerente.
Celle attiveCelle che passano i gate corr/rms/stable nell’update corrente e contribuiscono a mappe/istogrammi.
Spettro / istogrammaDistribuzione delle frequenze per-cella nella ROI (eventualmente pesata con corr/rms).
WaterfallStorico nel tempo degli spettri; utile per vedere drift, burst e cambi di banda.
Oscillatore blobStima “a livello ROI”: produce Hz(t) e Coh(t) sull’insieme di celle stabili.
Hz(t)Traccia della frequenza dominante di regione (un valore per update) dall’oscillatore blob.
CohCoerenza (0..1): rapporto di allineamento di fase tra celle stabili; alta ⇒ “tipo oscillatore unico”.
DFT / FFTTrasformata discreta di Fourier / versione veloce (FFT) usate per cercare picchi in spettro.
GoertzelDFT efficiente su un singolo bin (quando serve una sola frequenza).
UVCUSB Video Class (interfaccia standard per camere USB su Windows).
BW gain / Color gain / Alpha boostGuadagni di visualizzazione: luminosità B/N, saturazione colore e forza della trasparenza overlay.
quality (%)Rapporto globale di inlier (frazione di pixel/celle affidabili), indicatore rapido della “salute” dell’acquisizione.

Fine documento.


Appendice A) Formati UVC: pixel format, codec e contenitori di registrazione (MP4, AVI, …)

Questa appendice chiarisce un equivoco molto comune: il formato in uscita dalla camera (cosa trasmette il dispositivo UVC su USB) non è lo stesso del formato del file (cosa salvi su disco). Le camere UVC tipicamente trasmettono:

Quando registri su disco scegli di solito un contenitore (es. MP4 o AVI) e un codec (es. H.264 o MJPG). L’applicazione (tramite OpenCV / backend multimediali del sistema) codifica i frame in ingresso nel codec scelto.

A.1 UVC: cosa esce dalla camera

UVC (USB Video Class) è uno standard che permette alle camere di esporre stream video con un insieme di formati e risoluzioni supportati. Famiglie tipiche:

Scelta pratica. Se la banda USB non è un problema e ti interessano micro-moti, preferisci non compresso o compressione leggera. Se ti serve alta risoluzione o FPS elevati su USB2, MJPG è spesso l’unica scelta realistica.

A.2 Pixel format ≠ codec (perché “YUV” non è “MP4”)

“YUV” (più correttamente Y′CbCr) descrive l’organizzazione dei pixel (come sono memorizzati luma e croma), non un contenitore file. MP4 è un contenitore che trasporta tipicamente stream compressi (H.264/H.265/AV1). In generale non si memorizza YUY2 “grezzo” dentro MP4. La catena tipica è:

Camera UVC esce in YUY2 (frame grezzi) → applicazione converte in BGR/grigio → encoder comprime in H.264 → file MP4

Oppure, se la camera esce in MJPG:

Camera UVC esce in MJPG (frame compressi) → decoder in BGR/grigio → (opzionale) ricodifica → file MP4/AVI

A.3 Contenitori e codec (combinazioni tipiche)

ContenitoreCodec comuniNote
MP4H.264 (AVC), H.265 (HEVC), AV1Molto efficiente; a bitrate basso può introdurre artefatti; attenzione a sorgenti a framerate variabile (VFR).
AVIMJPG, XVID/DivX, non compressoSemplice e compatibile; ottimo per MJPG; il file cresce molto se non compresso.
MKVH.264/H.265, VP9, AV1Contenitore flessibile; dipende dal supporto del backend.

I codec effettivamente disponibili dipendono dal backend OS (Windows Media Foundation / DirectShow) e dalla build di OpenCV.

A.4 Perché i formati contano nelle misure di moto/oscillazione

A.5 Dritte rapide di troubleshooting

Appendice B) Pannelli, dock widget e layout (Qt)

FlowStudio usa il modello tipico di QMainWindow (Qt): la finestra è composta da una vista centrale e da vari dock widget (pannelli agganciabili) attorno. Se non hai familiarità con Qt, questa appendice spiega come far ricomparire, spostare e ridimensionare i pannelli.

B.1 Mostrare / nascondere un pannello

B.2 Spostare e ancorare (dock)

B.3 Tab, colonne e split

B.4 Ridimensionare le sezioni

B.5 Ripristinare il layout

B.6 Trucchi rapidi