Stesso dataset, due motori: come confrontare ODM e ODX

Avanzato Entrambe le linee 14 min di lettura

Ultimo aggiornamento:

Testato con: ODX (webodm/odm, verifica il tag) via WebODM 3.2.8; ODM 3.6.0 (opendronemap/odm)

In questa pagina

Perché un protocollo e non un numero#

La linea WebODM descrive ODX come "forked from and faster than ODM" (webodm.org, verificato il 2 settembre 2026). La linea OpenDroneMap non pubblica, alla data di verifica, un confronto con ODX. Nei forum circolano tempi e percentuali senza hardware, versioni e dataset dichiarati: nessuno ti dice cosa succederà sulla tua macchina.

Questa guida non contiene risultati: contiene il metodo. Lo dichiariamo per iscritto: alla data di pubblicazione non abbiamo ancora risultati nostri; li pubblicheremo nel blog con questo protocollo, con dataset, hardware, versioni e digest delle immagini, così che tu possa ripeterli.

Termini usati: "RMSE" (root mean square error) è l'indicatore standard di accuratezza; "check point" è un punto misurato a terra ma escluso dal calcolo; "digest" è l'identificativo univoco di un'immagine Docker. Definizioni nel glossario.

I principi#

Un confronto è valido solo se cambia una cosa sola: il motore.

  1. Hardware identico: la stessa macchina fisica, non due macchine "simili".
  2. Stesso dataset: le stesse immagini, senza pre-elaborazioni diverse; per la riproducibilità pubblica, un dataset libero.
  3. Stesse opzioni: un preset in formato testo con solo opzioni comuni ai due motori.
  4. Stessa via di esecuzione: riga di comando con Docker, per entrambi; l'interfaccia web aggiunge variabili che non vogliamo misurare.
  5. Ripetizioni: almeno 3 per motore, alternate, perché la prima esecuzione soffre della cache fredda.
  6. Tutto annotato prima di partire: versioni, digest, hardware, preset, dataset.

1. Preparare l'ambiente#

Annota in un file ambiente.txt: CPU e numero di core, RAM, tipo di disco, GPU e versione del driver, sistema operativo, versione di Docker. Su Linux bastano lscpu, free -h, nvidia-smi, lsblk e docker --version. Se usi Docker Desktop, annota RAM e CPU assegnate in Settings → Resources.

Poi scarica le due immagini e registra versione e digest.

WebODM / ODX

Verifica su Docker Hub il tag di webodm/odm e usalo al posto di TAG:

bash
docker pull webodm/odm:TAG
docker run --rm webodm/odm:TAG --version
docker inspect --format '{{.Id}} {{index .RepoDigests 0}}' webodm/odm:TAG
OpenDroneMap / ODM
bash
docker pull opendronemap/odm
docker run --rm opendronemap/odm --version
docker inspect --format '{{.Id}} {{index .RepoDigests 0}}' opendronemap/odm

Anche qui puoi fissare un tag esplicito consultando Docker Hub.

Salva gli output in ambiente.txt. Il digest (sha256:…) permette a chiunque di scaricare esattamente la tua immagine anche quando il tag sarà cambiato.

GPU: decidi prima. Le due documentazioni divergono: docs.webodm.org documenta l'accelerazione dell'estrazione feature e ODX ha annunciato il supporto RTX serie 50 (12 luglio 2026); docs.opendronemap.org dichiara che la "GPU currently provides no performance benefit". Due scelte, da dichiarare nel report: confronto CPU, con --no-gpu per entrambi; oppure confronto con GPU, con NVIDIA Container Toolkit e --gpus all per entrambi. Non mescolarle nella stessa tabella.

2. Il dataset e i check point#

Per un confronto ripetibile da altri usa un dataset pubblico: il repository ODMdata (github.com/OpenDroneMap/ODMdata) ne raccoglie diversi, alcuni con file GCP; la guida Dataset di prova li descrive. Scegli in base alla RAM: per la documentazione di WebODM, 4 GB per 40 immagini, 16 GB per 250 (Requisiti hardware). Se usi un dataset tuo, descrivilo: numero di immagini, quota, GSD, GCP.

Copia il dataset in due cartelle identiche, una per motore:

bash
mkdir -p /home/utente/benchmark/odx/images /home/utente/benchmark/odm/images
cp /home/utente/dataset/*.JPG /home/utente/benchmark/odx/images/
cp /home/utente/dataset/*.JPG /home/utente/benchmark/odm/images/

Se c'è un file GCP, copia lo stesso gcp_list.txt in entrambe le cartelle di progetto.

Per misurare l'accuratezza servono punti che il motore non conosce. Dal file GCP completo tieni fuori almeno 3 punti (meglio 5) ben distribuiti e salvali in checkpoints.txt, con lo stesso sistema di riferimento; il gcp_list.txt passato ai motori contiene solo i punti di controllo, uguali per entrambi. Questo metodo vale su entrambe le linee alla data di verifica; la funzione "checkpoint" annunciata da ODX il 12 luglio 2026 esiste in una sola linea e quindi non la usiamo nel protocollo. Formato del file in Punti di controllo a terra.

3. Il preset#

Scrivi il preset come testo, con solo opzioni comuni. Un esempio per ortofoto, DSM e nuvola:

testo
# preset: benchmark-01
# opzioni comuni a ODM 3.6.0 e ODX (6 aprile 2026); verificato il 2 settembre 2026
--dsm
--pc-quality medium
--feature-quality high
--orthophoto-resolution 5
--dem-resolution 5
--pc-las
--max-concurrency 8
--no-gpu

Fissa --max-concurrency al numero di core che vuoi usare, uguale per entrambi: al default ogni motore potrebbe decidere diversamente. Togli --no-gpu per il confronto con GPU. Se il dataset ha GCP, aggiungi --gcp /datasets/odx/gcp_list.txt e --gcp /datasets/odm/gcp_list.txt nei rispettivi comandi. Prima delle misure, verifica con il metodo di Opzioni a confronto che ogni opzione compaia nel --help di entrambe le immagini.

4. Eseguire e misurare#

Tempo totale#

Il comando time della shell misura il tempo di parete dell'intero docker run, cioè quanto hai aspettato.

WebODM / ODX
bash
cd /home/utente/benchmark
time docker run --rm -v /home/utente/benchmark:/datasets webodm/odm:TAG --project-path /datasets odx $(grep -v '^#' benchmark-01.txt | tr '\n' ' ') 2>&1 | tee odx-run1.log
OpenDroneMap / ODM
bash
cd /home/utente/benchmark
time docker run --rm -v /home/utente/benchmark:/datasets opendronemap/odm --project-path /datasets odm $(grep -v '^#' benchmark-01.txt | tr '\n' ' ') 2>&1 | tee odm-run1.log

Il valore real è il tempo totale; il log salvato con tee contiene i tempi delle singole fasi. Ripeti almeno 3 volte per motore, alternando (ODX, ODM, ODX, ODM, …). Prima di ogni esecuzione svuota la cartella del progetto lasciando solo images e il file GCP, altrimenti il motore riprende da dove si era fermato.

RAM di picco#

Attenzione: /usr/bin/time -v riporta la memoria massima del processo che lancia, ma con docker run quel processo è il client Docker, non il container; il valore sarebbe di pochi megabyte e privo di significato. Usa docker stats, che legge la memoria del container, campionandolo da un secondo terminale. Avvia questo ciclo prima del docker run e fermalo con Ctrl+C alla fine:

bash
while true; do docker stats --format '{{.Name}} {{.MemUsage}}' --no-stream >> ram.log; sleep 5; done

Il picco è il valore più alto in ram.log. Un campionamento a 5 secondi può perdere picchi brevi: dichiaralo. Se esegui il motore in modo nativo, senza Docker, /usr/bin/time -v è appropriato e il campo "Maximum resident set size" è il picco.

Accuratezza: RMSE sui check point#

Apri ortofoto e DSM di ciascun motore in QGIS. Per ogni check point leggi X e Y del centro del segno sull'ortofoto e Z dal DSM nello stesso punto; calcola le differenze rispetto alle coordinate misurate e l'RMSE per X, Y, Z e planimetrico. Procedimento e foglio di calcolo in Accuratezza e validazione. Stesso operatore e stesso zoom per entrambe le ortofoto. Il report di qualità dei motori riguarda i GCP usati nel calcolo e non sostituisce i check point (Leggere il report di qualità).

Densità della nuvola#

Conta i punti della nuvola georeferenziata in CloudCompare (proprietà della nuvola) oppure con PDAL:

bash
pdal info --summary percorso/della/nuvola.laz | grep -i count

Nome e percorso del file sono documentati nelle pagine sugli output di ciascuna linea. Registra punti e superficie, per ricavare la densità per metro quadrato.

Copertura dell'ortofoto#

In QGIS, ritaglia le due ortofoto con lo stesso poligono dell'area di interesse e conta i pixel nodata con le statistiche zonali o con gdalinfo -stats; riporta la percentuale. Affianca due schermate della stessa zona critica alla stessa scala.

Dimensione degli output#

bash
du -sh /home/utente/benchmark/odx/* /home/utente/benchmark/odm/*
Due terminali affiancati: a sinistra time docker run con webodm/odm, a destra il ciclo docker stats che campiona la RAM

5. Riportare i risultati#

Il report ha tre parti: la scheda dell'esperimento, la tabella dei risultati e il materiale allegato.

Voce WebODM / ODX OpenDroneMap / ODM
Immagine Docker e tag webodm/odm:TAG opendronemap/odm:TAG
Digest (docker inspect) sha256:… sha256:…
Output di --version
Preset benchmark-01 (testo allegato) benchmark-01 (identico)
Modalità GPU --no-gpu oppure GPU condivisa (dichiarare) idem
Dataset nome, fonte, numero immagini, GSD, GCP idem
Hardware CPU, core, RAM, disco, GPU, driver, SO, Docker idem
Ripetizioni 3 o più 3 o più
Verificato il 2 settembre 2026 2 settembre 2026

Per ogni metrica riporta la mediana delle ripetizioni e l'intervallo minimo–massimo: la mediana è meno sensibile a un'esecuzione anomala.

Metrica WebODM / ODX OpenDroneMap / ODM
Tempo totale, mediana (min–max)
RAM di picco, mediana (min–max), campionamento 5 s
RMSE X / Y / Z sui check point (n = …)
RMSE planimetrico
Punti nella nuvola / densità (punti/m²)
Pixel nodata nell'area di interesse (%)
Dimensione totale degli output
Verificato il data delle misure data delle misure

Allega ambiente.txt, il preset, checkpoints.txt, i log di ogni esecuzione, ram.log, il foglio di calcolo dell'RMSE e le schermate: chi vuole ripetere il test non deve chiederti nulla.

6. Come pubblicare#

Pubblica risultati completi: un tempo senza RMSE racconta metà della storia. Dichiara i limiti (campionamento della RAM, un dataset, un hardware, un preset). Non generalizzare: "su questo dataset e questo hardware, con questo preset, il motore A ha impiegato X e il motore B Y" è corretto; "A è più veloce di B" non lo è. Data tutto: un confronto di settembre 2026 non descrive i motori di marzo 2027. Segnala i risultati a entrambi i progetti (Discord di WebODM; forum community.opendronemap.org) con lo stesso testo.

Se vuoi che i tuoi risultati compaiano su webodm.it, inviaceli con il materiale allegato tramite Contatti: li pubblicheremo nel blog citando l'autore, purché seguano questo protocollo. Faremo lo stesso con le nostre misure, ogni sei mesi, con le versioni correnti.

Come verificare

Il protocollo è completo se puoi rispondere sì a tutto:

  1. ambiente.txt contiene hardware, versioni e digest di entrambe le immagini.
  2. Il preset contiene solo opzioni presenti nel --help di entrambe le immagini e fissa --max-concurrency e la modalità GPU.
  3. Hai almeno 3 esecuzioni per motore, alternate, con cartelle di progetto pulite.
  4. La RAM è misurata con docker stats (o con /usr/bin/time -v solo per esecuzioni native).
  5. I check point sono fuori dal file GCP e sono gli stessi per entrambi.
  6. Il report riporta mediana e intervallo, non un singolo valore.

Problemi frequenti#

Un motore fallisce con il preset. Un'opzione non è comune alle due versioni scaricate. Ripeti il confronto --help e togli l'opzione, oppure documenta il fallimento come risultato: è un dato.

L'RMSE è alto per entrambi. Il problema è quasi sempre nei dati (GCP mal distribuiti, sistema di riferimento diverso, quote ellissoidiche contro ortometriche), non nei motori. Vedi Sistemi di riferimento italiani.

Prossimi passi#

Fonti

Guide correlate