165 lines
10 KiB
Markdown
165 lines
10 KiB
Markdown
# Specifiche e Considerazioni di Design: Editor Visuale Intelligente
|
|
|
|
Questo documento raccoglie l'analisi e le specifiche di design per l'implementazione del sistema di **Scansione Fotocamera & AI** per la digitalizzazione rapida dei canti nella PWA.
|
|
L'obiettivo è progettare un'esperienza utente a "sfregamento zero" (zero friction), robusta anche in ambienti ostili (es. chiese senza campo) e capace di gestire le imperfezioni storiche dei libretti parrocchiali.
|
|
|
|
---
|
|
|
|
## 1. Architettura della Pipeline Visiva
|
|
|
|
Il processo si basa su un'interazione fluida tra client (PWA), proxy server ed il motore multimodale di visione artificiale (Google Gemini 2.5 Flash).
|
|
|
|
```mermaid
|
|
graph TD
|
|
A[Inquadratura Fotocamera PWA] --> B[Compressione Client Canvas JPEG ~200KB]
|
|
B --> C{Connessione Rete?}
|
|
C -- Online --> D[Invia POST a /scanSong]
|
|
C -- Offline --> E[Salva in IndexedDB localmente]
|
|
E --> F[In attesa di Connessione...]
|
|
F --> C
|
|
D --> G[Chiamata a Gemini 2.5 Flash]
|
|
G --> H[Analisi Spaziale ed Estrazione JSON]
|
|
H --> I[Popolamento Automatico dell'Editor PWA]
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Casi d'Uso Avanzati e Soluzioni Specifiche
|
|
|
|
### A. Gestione Multi-Pagina (Canti Lunghi)
|
|
* **Problema**: Molti canti liturgici (es. Salmi o canti d'ingresso lunghi) si sviluppano su due pagine adiacenti o su foglietti fronte-retro separati.
|
|
* **Soluzione**: L'interfaccia dell'editor consentirà all'utente di aggiungere più scatti all'interno della stessa sessione di scansione prima dell'invio.
|
|
* **Gestione AI**: Le immagini verranno inviate in blocco al modello di visione (sfruttando l'enorme finestra di contesto di Gemini). Il prompt istruirà l'IA a considerare le foto come sequenziali, unendo il testo in un unico flusso coerente senza duplicare il titolo ed ordinando le strofe in modo corretto.
|
|
|
|
### B. Correzione dei Refusi Storici (Libretti Anni '90)
|
|
* **Problema**: I libretti parrocchiali stampati decenni fa o digitati a macchina presentano spesso refusi tipografici, lettere scambiate o scorrettezze sugli accenti (es. `perche'` al posto di `perché`, `piu'` per `più`, `Gesu'` per `Gesù`).
|
|
* **Soluzione**: Sfruttando la comprensione semantica del modello di linguaggio (LLM), l'IA non effettua una mera trascrizione pixel-per-pixel, ma analizza il senso delle parole nel contesto dei canti liturgici italiani (molti dei quali fanno già parte della sua conoscenza pregressa).
|
|
* **Risultato**: Restituzione di un testo grammaticalmente perfetto e pulito, correggendo automaticamente i vecchi accenti e gli errori di battitura della carta originale.
|
|
|
|
### C. Traduzione ed Uniformazione degli Accordi
|
|
* **Problema**: Gli spartiti o canzonieri cartacei possono utilizzare la notazione internazionale (`C, D, E, F, G, A, B`) anziché la notazione latina standard italiana (`Do, Re, Mi, Fa, Sol, La, Si`).
|
|
* **Soluzione**: Nel prompt di sistema, l'IA viene istruita ad uniformare tutti gli accordi alla notazione italiana standard.
|
|
* **Esempio**: Se l'utente inquadra un canzonierino scout o internazionale scritto in notazione inglese (es. `[C] [G] [Am]`), il sistema lo tradurrà istantaneamente in `[Do] [Sol] [Lam]` prima di inviarlo all'editor della PWA, garantendo la compatibilità al 100% con il modulo di trasposizione interna dei toni.
|
|
|
|
---
|
|
|
|
## 3. Strategia Offline (Resilienza in Chiesa)
|
|
|
|
Le chiese sono notoriamente ambienti difficili per la connettività di rete (mura in pietra spesse, sotterranei, assenza di ripetitori vicini). Il sistema non deve dipendere da una connessione sempre attiva.
|
|
|
|
### Flusso Offline con IndexedDB
|
|
1. L'utente scatta la foto (o seleziona l'immagine) dall'editor mentre si trova offline.
|
|
2. L'app converte l'immagine in `Blob` e la salva localmente all'interno di **IndexedDB** associandola a una coda di scansioni pendenti (`scan-offline-queue`).
|
|
3. L'interfaccia mostra un avviso rassicurante:
|
|
> 💾 *Fogli acquisiti offline! L'app elaborerà automaticamente la scansione del canto non appena rileverai una connessione internet stabile.*
|
|
4. Il `ConnectivityService` della PWA monitora lo stato della rete. Non appena il dispositivo torna online (es. all'uscita dalla chiesa o sotto WiFi):
|
|
* L'app estrae l'immagine da IndexedDB.
|
|
* Effettua la chiamata POST a `/scanSong`.
|
|
* Riceve il JSON tradotto e notifica l'utente (o precompila la scheda dei canti proposti).
|
|
|
|
---
|
|
|
|
## 4. Specifiche del Prompt di Sistema (System Prompt)
|
|
|
|
L'output del backend deve essere rigidamente controllato e tipizzato per consentire al client Angular di digerirlo senza eccezioni di parsing. Il prompt di sistema da implementare sul proxy API sarà il seguente:
|
|
|
|
```text
|
|
Sei un OCR musicale multimodale specializzato in canti liturgici e religiosi cristiani.
|
|
Analizza l'immagine fornita (o il set di immagini sequenziali) e restituisci ESCLUSIVAMENTE un oggetto JSON valido. Non aggiungere spiegazioni o markdown.
|
|
|
|
Schema JSON di risposta:
|
|
{
|
|
"titolo": "String (titolo del canto)",
|
|
"autore": "String o null",
|
|
"sezioni": [
|
|
{
|
|
"tipo": "ritornello" | "strofa",
|
|
"numero": Number o null (solo per le strofe, es. 1, 2, 3),
|
|
"righe": [
|
|
"Testo completo della riga con accordi musicali inseriti in linea tra parentesi quadre prima della sillaba corretta. Es: [Do]Tu sei la mia [Sol]vita"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
|
|
Regole di formattazione:
|
|
1. Traduci tutti gli accordi in notazione italiana (Do, Re, Mi, Fa, Sol, La, Si, con 'm' per i minori, '7' per le settime, ecc.).
|
|
2. Inserisci gli accordi esattamente nel punto in cui cadono spazialmente sopra le parole dell'immagine.
|
|
3. Correggi accenti storici errati (es. trasformando 'perche'' in 'perché') e refusi evidenti.
|
|
```
|
|
|
|
Questo approccio garantisce che la PWA riceva un formato perfettamente strutturato e pronto per essere inserito direttamente nelle righe del database locale.
|
|
|
|
---
|
|
|
|
## 5. Approccio 100% Locale e Gratuito (Client-Side)
|
|
|
|
Se il vincolo fondamentale è **non utilizzare alcun servizio cloud a pagamento o esterno**, possiamo spostare l'intero carico di elaborazione (OCR ed allineamento) **direttamente all'interno del browser dell'utente (client-side)** in modo 100% gratuito ed autonomo.
|
|
|
|
Ciò è realizzabile integrando due componenti open-source nella PWA:
|
|
|
|
1. **Tesseract.js** (compilato in WebAssembly per il browser): si occupa di estrarre il testo e, soprattutto, di fornirci i metadati spaziali di ogni singola parola.
|
|
2. **Algoritmo Euristico di Allineamento Spaziale**: un algoritmo scritto da noi in TypeScript che mappa la posizione fisica degli accordi rispetto al testo.
|
|
|
|
### Come funziona l'algoritmo di allineamento locale?
|
|
|
|
Quando Tesseract.js scansiona l'immagine, non restituisce solo una stringa, ma un array di parole in cui ogni parola contiene il testo ed il suo **Bounding Box (rettangolo di coordinate fisiche sull'immagine: `x0`, `y0`, `x1`, `y1`)**:
|
|
|
|
```typescript
|
|
interface OCRWord {
|
|
text: string;
|
|
bbox: { x0: number; y0: number; x1: number; y1: number };
|
|
}
|
|
```
|
|
|
|
L'algoritmo elabora questi dati in 4 fasi:
|
|
|
|
#### Fase 1: Raggruppamento in Righe Fisiche
|
|
Le parole vengono ordinate per coordinata `y0`. Le parole che hanno valori di `y0` simili (con una tolleranza basata sull'altezza dei caratteri, es. ±15 pixel) vengono raggruppate nella stessa **riga orizzontale**.
|
|
|
|
#### Fase 2: Classificazione delle Righe (Accordi vs. Testo)
|
|
Ogni riga viene analizzata per determinare la sua natura:
|
|
* **Riga di Accordi**: Se più del 70% delle parole nella riga corrisponde a pattern di accordi noti (es. parole corte come `Do`, `Sol`, `Re7`, `Lam`, `C`, `G`, `D7`), la riga viene marcata come riga di accordi.
|
|
* **Riga di Testo**: In tutti gli altri casi, viene considerata una riga di testo normale.
|
|
|
|
#### Fase 3: Mappatura e Iniezione degli Accordi
|
|
Per ogni **Riga di Accordi**, individuiamo la **Riga di Testo** immediatamente sottostante (quella con coordinata `y` successiva più vicina).
|
|
Per ciascun accordo presente nella riga:
|
|
1. Calcoliamo la sua coordinata orizzontale centrale: `x_accordo = (bbox.x0 + bbox.x1) / 2`.
|
|
2. Scorriamo le parole della riga di testo sottostante per trovare quale parola (o lettera) ha la coordinata `x` più vicina a `x_accordo`.
|
|
3. Inseriamo la stringa dell'accordo tra parentesi quadre (es. `[Re]`) esattamente prima di quella parola nel testo finale.
|
|
|
|
```text
|
|
Spaziatura fisica sull'immagine:
|
|
Riga 1 (Accordi): [Do] [Sol]
|
|
Riga 2 (Testo): Tu sei la mia vita, altro io non ho.
|
|
↑ ↑
|
|
x=120 x=480
|
|
```
|
|
|
|
#### Fase 4: Segmentazione Strutturale delle Sezioni
|
|
L'algoritmo identifica i cambi di sezione (es. il passaggio da Ritornello a Strofa) misurando lo spazio verticale (`gap y`) tra le righe di testo. Un distanziamento verticale significativamente maggiore della media indica una separazione di strofa, consentendo di dividere il canto in blocchi strutturati.
|
|
|
|
### Pro e Contro dell'Approccio Locale
|
|
|
|
| Vantaggi | Svantaggi |
|
|
| :--- | :--- |
|
|
| 🟢 **100% Gratuito**: Nessun costo di licenza o API esterne. | 🔴 **Uso Risorse**: L'elaborazione OCR avviene sul telefono dell'utente (richiede 3-5 secondi). |
|
|
| 🟢 **Totale Privacy**: Le immagini non lasciano mai il dispositivo. | 🔴 **Meno tolleranza alle pieghe**: Rispetto a Gemini, un OCR locale soffre di più se la foto è storta o con ombre. |
|
|
| 🟢 **Funzionamento Offline**: Funziona anche nel deserto, senza alcuna rete. | 🔴 **Nessuna correzione lessicale**: Non corregge gli errori grammaticali storici del foglio cartaceo. |
|
|
|
|
---
|
|
|
|
## 6. Il Compromesso Ideale: Gemini API Free Tier
|
|
|
|
Esiste una terza via che unisce il meglio dei due mondi (la precisione assoluta dell'AI e il costo zero): **il Free Tier delle API di Google Gemini 2.5 Flash**.
|
|
|
|
Google offre tramite **Google AI Studio** un piano d'uso completamente gratuito con i seguenti limiti:
|
|
* **15 Richieste al minuto (RPM)**
|
|
* **1500 Richieste al giorno (RPD)**
|
|
|
|
Per un'applicazione di canti religiosi dove l'aggiunta di nuovi brani è un'operazione sporadica (eseguita da pochi amministratori/chitarristi solo quando si impara un canto nuovo), **questi limiti gratuiti non verranno mai superati**.
|
|
|
|
* **Implementazione sicura**: Per evitare di inserire la chiave API gratuita all'interno del codice frontend (dove chiunque potrebbe rubarla), si fa passare la richiesta attraverso una semplice funzione serverless gratuita (es. su *Vercel Free Tier* o *Cloudflare Workers*), che funge da proxy sicuro e vi applica la chiave API prima di chiamare Google.
|
|
|