Milestone YOLO11 navigation planning baseline
This commit is contained in:
255
flywms_navigate_spec.rtf
Normal file
255
flywms_navigate_spec.rtf
Normal file
@@ -0,0 +1,255 @@
|
||||
{\rtf1\ansi\deff0
|
||||
{\fonttbl{\f0 Calibri;}{\f1 Consolas;}}
|
||||
\fs24
|
||||
\b Specifica flywms_navigate - navigazione geometrica e snapshot UDC\b0\par
|
||||
\par
|
||||
\b 1. Obiettivo\b0\par
|
||||
Realizzare uno script separato, chiamato flywms_navigate.py, che usi solo la parte detector YOLO/Ultralytics per simulare la navigazione laterale di un drone davanti a una scaffalatura.\par
|
||||
\par
|
||||
Lo script non deve ancora fare OCR. Deve invece osservare i gaylord rilevati nel video, seguirli per alcuni frame, capire quando uno di essi si trova in posizione utile al centro della visuale, e generare un evento testuale equivalente a:\par
|
||||
\f1
|
||||
STOP\par
|
||||
SCATTA_FOTO\par
|
||||
ASSOCIA_POSIZIONE gaylord_N\par
|
||||
RIPARTI_DESTRA\par
|
||||
\f0
|
||||
\par
|
||||
In questa fase la posizione reale del drone viene simulata con una sequenza logica: gaylord 1, gaylord 2, gaylord 3, ecc.\par
|
||||
\par
|
||||
Il punto fondamentale e' separare la guida dal riconoscimento codice. Il detector lavora sul flusso video live e decide quando congelare uno snapshot. L'OCR lavorera' dopo, su uno snapshot gia' scelto, insieme alla posizione del drone registrata nel momento corretto.\par
|
||||
\par
|
||||
\b 2. Problema che vogliamo risolvere\b0\par
|
||||
Nella pipeline attuale il video continua a scorrere mentre YOLO e OCR lavorano in asincrono. Questo va bene per misurare prestazioni, ma non va bene per la geometria della navigazione: quando arriva il risultato OCR, la posizione del drone potrebbe essere gia' cambiata.\par
|
||||
\par
|
||||
Per la navigazione non dobbiamo aspettare l'OCR per decidere dove siamo. Dobbiamo invece creare un pacchetto dati congelato nel momento in cui la geometria dice che il gaylord e' nella posizione giusta.\par
|
||||
\par
|
||||
\f1
|
||||
NavigationSnapshot\par
|
||||
snapshot_id\par
|
||||
frame_id\par
|
||||
timestamp_video\par
|
||||
simulated_position = "gaylord N"\par
|
||||
drone_pose_simulata\par
|
||||
track_id\par
|
||||
gaylord_bbox\par
|
||||
gaylord_center\par
|
||||
gaylord_area\par
|
||||
frame_image\par
|
||||
quality_score opzionale\par
|
||||
\f0
|
||||
\par
|
||||
Questo oggetto potra' poi essere mandato all'OCR o al backend WMS senza perdere il legame con la posizione.\par
|
||||
\par
|
||||
\b 3. Concetto di tracking leggero\b0\par
|
||||
Il tracking leggero serve a capire che un bbox rilevato nel frame corrente e' probabilmente lo stesso oggetto visto nei frame precedenti.\par
|
||||
\par
|
||||
Non serve ancora un tracker complesso come DeepSORT. Per questa prima versione basta associare i bbox di frame consecutivi usando regole geometriche semplici:\par
|
||||
\par
|
||||
- vicinanza del centro bbox;\par
|
||||
- sovrapposizione tra bbox, cioe' IoU;\par
|
||||
- continuita' della dimensione/area;\par
|
||||
- coerenza del movimento orizzontale.\par
|
||||
\par
|
||||
Ogni gaylord seguito nel tempo diventa una traccia, cioe' una Track.\par
|
||||
\par
|
||||
\f1
|
||||
Track\par
|
||||
id\par
|
||||
bbox corrente\par
|
||||
center corrente\par
|
||||
area corrente\par
|
||||
bbox_history ultimi N frame\par
|
||||
center_history ultimi N frame\par
|
||||
area_history ultimi N frame\par
|
||||
first_seen_frame\par
|
||||
last_seen_frame\par
|
||||
hits = quante volte e' stato visto\par
|
||||
missed = quanti frame consecutivi non e' stato visto\par
|
||||
state = entering | candidate | centered | snapshotted | exiting | lost\par
|
||||
already_snapshotted = true/false\par
|
||||
\f0
|
||||
\par
|
||||
Se in un frame YOLO rileva tre gaylord, il tracker mantiene tre tracce diverse. Una puo' uscire verso sinistra, una puo' essere al centro, una puo' entrare da destra.\par
|
||||
\par
|
||||
\b 4. Associazione detection-track\b0\par
|
||||
Per ogni frame:\par
|
||||
\par
|
||||
1. YOLO produce una lista di bbox di classe gaylord.\par
|
||||
2. Per ogni detection si cerca la Track esistente piu' compatibile.\par
|
||||
3. La compatibilita' puo' essere calcolata con uno score:\par
|
||||
\par
|
||||
\f1
|
||||
score = 0.7 * IoU(track.bbox, detection.bbox)\par
|
||||
+ 0.3 * center_similarity(track.center, detection.center)\par
|
||||
\f0
|
||||
\par
|
||||
4. Se lo score supera una soglia, la detection aggiorna quella Track.\par
|
||||
5. Se nessuna Track e' compatibile, nasce una nuova Track.\par
|
||||
6. Le Track non aggiornate aumentano missed.\par
|
||||
7. Se missed supera una soglia, la Track diventa lost e viene rimossa.\par
|
||||
\par
|
||||
Per una prima implementazione possiamo anche partire con una regola piu' semplice: associare al track piu' vicino se la distanza tra centri e' minore di una certa percentuale della larghezza immagine. Poi raffiniamo con IoU.\par
|
||||
\par
|
||||
\b 5. Come decidere quando scattare\b0\par
|
||||
Lo snapshot deve avvenire quando una Track rappresenta un gaylord utile, cioe' non tagliato, abbastanza grande, stabile e vicino al centro della visuale.\par
|
||||
\par
|
||||
Criteri iniziali proposti:\par
|
||||
\par
|
||||
- classe = gaylord;\par
|
||||
- bbox non tagliato dai bordi immagine, con margine minimo configurabile;\par
|
||||
- area bbox sopra una soglia minima;\par
|
||||
- centro X bbox dentro una fascia centrale configurabile;\par
|
||||
- centro Y dentro una fascia utile verticale configurabile;\par
|
||||
- Track vista per almeno N frame;\par
|
||||
- area non sta piu' crescendo in modo forte, oppure e' abbastanza stabile;\par
|
||||
- la Track non ha gia' generato snapshot.\par
|
||||
\par
|
||||
La fascia centrale puo' essere visualizzata nella finestra debug con due linee verticali:\par
|
||||
\par
|
||||
\f1
|
||||
center_x = frame_width / 2\par
|
||||
tolerance = frame_width * 0.10\par
|
||||
zona_centrale = [center_x - tolerance, center_x + tolerance]\par
|
||||
\f0
|
||||
\par
|
||||
Quando il centro del gaylord entra in questa zona e i criteri sono soddisfatti, lo script genera:\par
|
||||
\par
|
||||
\f1
|
||||
[NAV] track=4 centered frame=1234 pos=gaylord 7\par
|
||||
[CMD] STOP\par
|
||||
[CMD] SCATTA_FOTO snapshot_0007.jpg\par
|
||||
[CMD] ASSOCIA_POSIZIONE gaylord 7\par
|
||||
[CMD] RIPARTI_DESTRA delay=1.0s\par
|
||||
\f0
|
||||
\par
|
||||
\b 6. Gestione del migliore snapshot\b0\par
|
||||
Invece di scattare una sola immagine esattamente quando il centro entra nella fascia, possiamo raccogliere un piccolo gruppo di candidate snapshot per la stessa Track.\par
|
||||
\par
|
||||
Esempio:\par
|
||||
\par
|
||||
- quando la Track entra nella fascia centrale, si apre una finestra temporale di selezione;\par
|
||||
- per i successivi K frame compatibili si calcola un punteggio;\par
|
||||
- alla fine si salva solo il migliore.\par
|
||||
\par
|
||||
Punteggio iniziale:\par
|
||||
\par
|
||||
\f1
|
||||
center_score = 1 - abs(bbox_center_x - frame_center_x) / center_tolerance\par
|
||||
size_score = normalized_bbox_area\par
|
||||
cut_score = 1 se bbox non tagliato, 0 se tagliato\par
|
||||
sharpness_score = opzionale, non obbligatorio per la geometria\par
|
||||
\par
|
||||
snapshot_score = 0.50 * center_score\par
|
||||
+ 0.30 * size_score\par
|
||||
+ 0.20 * cut_score\par
|
||||
\f0
|
||||
\par
|
||||
Per ora non usiamo OCR e non usiamo il filtro blur come vincolo primario, perche' il detector riesce a localizzare anche immagini leggermente sfocate. La nitidezza potra' entrare solo come criterio secondario per scegliere la foto migliore da passare all'OCR.\par
|
||||
\par
|
||||
\b 7. Pseudocodice generale\b0\par
|
||||
\f1
|
||||
inizializza YOLO Ultralytics\par
|
||||
apri video o camera\par
|
||||
inizializza tracker vuoto\par
|
||||
inizializza snapshot_counter = 0\par
|
||||
inizializza simulated_position_counter = 0\par
|
||||
\par
|
||||
per ogni frame:\par
|
||||
frame_id += 1\par
|
||||
detections = yolo.detect(frame)\par
|
||||
gaylord_detections = filtra detections dove classe == "gaylord"\par
|
||||
\par
|
||||
tracker.update(gaylord_detections, frame_id)\par
|
||||
\par
|
||||
per ogni track attiva:\par
|
||||
calcola center_x, center_y, area\par
|
||||
calcola se bbox e' tagliato\par
|
||||
calcola trend area: crescente, stabile, decrescente\par
|
||||
calcola distanza dal centro frame\par
|
||||
\par
|
||||
se track e' eleggibile per snapshot:\par
|
||||
aggiungi frame corrente ai candidati della track\par
|
||||
aggiorna miglior candidato in base a snapshot_score\par
|
||||
\par
|
||||
se finestra candidati della track e' completa:\par
|
||||
snapshot_counter += 1\par
|
||||
simulated_position_counter += 1\par
|
||||
salva miglior frame candidato su disco\par
|
||||
crea NavigationSnapshot\par
|
||||
stampa comandi:\par
|
||||
STOP\par
|
||||
SCATTA_FOTO\par
|
||||
ASSOCIA_POSIZIONE gaylord simulated_position_counter\par
|
||||
RIPARTI_DESTRA\par
|
||||
marca track.already_snapshotted = true\par
|
||||
\par
|
||||
disegna debug:\par
|
||||
bbox gaylord\par
|
||||
track id\par
|
||||
centro bbox\par
|
||||
fascia centrale\par
|
||||
stato track\par
|
||||
ultimo comando generato\par
|
||||
\par
|
||||
mostra finestra flywms navigate\par
|
||||
\f0
|
||||
\par
|
||||
\b 8. Stati della Track\b0\par
|
||||
\f1
|
||||
entering\par
|
||||
\f0
|
||||
La Track e' appena nata o sta entrando nella visuale. Area spesso crescente, centro lontano dal centro frame.\par
|
||||
\par
|
||||
\f1
|
||||
candidate\par
|
||||
\f0
|
||||
La Track e' stabile, visibile da alcuni frame, non e' tagliata e si sta avvicinando alla zona centrale.\par
|
||||
\par
|
||||
\f1
|
||||
centered\par
|
||||
\f0
|
||||
Il centro bbox e' dentro la fascia centrale. La Track puo' produrre candidati snapshot.\par
|
||||
\par
|
||||
\f1
|
||||
snapshotted\par
|
||||
\f0
|
||||
La Track ha gia' prodotto uno snapshot. Non deve produrne altri, anche se resta visibile.\par
|
||||
\par
|
||||
\f1
|
||||
exiting\par
|
||||
\f0
|
||||
Il gaylord si sta allontanando dal centro o sta uscendo dalla visuale.\par
|
||||
\par
|
||||
\f1
|
||||
lost\par
|
||||
\f0
|
||||
La Track non viene piu' rilevata da troppi frame e viene rimossa.\par
|
||||
\par
|
||||
\b 9. Parametri iniziali suggeriti\b0\par
|
||||
\f1
|
||||
--center-tolerance-ratio 0.10\par
|
||||
--usable-y-min-ratio 0.15\par
|
||||
--usable-y-max-ratio 0.85\par
|
||||
--min-track-hits 3\par
|
||||
--max-track-missed 8\par
|
||||
--min-gaylord-area-ratio 0.04\par
|
||||
--edge-margin-ratio 0.02\par
|
||||
--snapshot-window-frames 5\par
|
||||
--snapshot-output-dir navigate_snapshots\par
|
||||
\f0
|
||||
\par
|
||||
\b 10. Output atteso della prima versione\b0\par
|
||||
La prima versione di flywms_navigate.py deve produrre:\par
|
||||
\par
|
||||
- una finestra video con bbox gaylord, track id e zona centrale;\par
|
||||
- log testuali dei comandi simulati;\par
|
||||
- immagini snapshot salvate su disco;\par
|
||||
- un file log CSV o JSONL con frame_id, track_id, bbox, posizione simulata e nome file snapshot;\par
|
||||
- nessuna dipendenza dall'OCR.\par
|
||||
\par
|
||||
\b 11. Nota sulla direzione di movimento\b0\par
|
||||
Per ora assumiamo movimento da sinistra verso destra del drone rispetto alla scaffalatura, come nel ragionamento iniziale. Nel video, pero', gli oggetti possono apparire con moto apparente non perfettamente regolare per via della ripresa manuale. Per questo la prima versione deve basarsi soprattutto sul centro del bbox e sulla continuita' della Track, non su un modello cinematico troppo rigido.\par
|
||||
\par
|
||||
\b 12. Passo successivo dopo questa specifica\b0\par
|
||||
Implementare flywms_navigate.py usando il detector Ultralytics gia' integrato in flywms.py, ma senza OCR. Quando la scelta degli snapshot sara' visivamente corretta, collegheremo ogni NavigationSnapshot alla pipeline OCR e poi alla logica WMS.\par
|
||||
}
|
||||
Reference in New Issue
Block a user