Newsgroup: it.comp.software.divx
Titolo: resizing

Gli algoritmi per cambiare la
risoluzione video dei vari software di
editing e/o encoding sono piů o meno
tutti uguali o qualcuno č migliore di
un altro?

 un altro?
alcuni sono piu' "accurati", alcuni lo sono meno;
quelli piu' accurati richiedono piu' tempo...
la maggior parte degli algoritmi e' basata sullo stesso schema
(il risultato e' calcolato come somma pesata dei pixel dell'immagine
di partenza) e differiscono solo per la funzione che calcola i
coefficienti (o pesi) a partire dalla distanza...
tale funzione e' sempre una funzione pari (simmetrica rispetto
all'asse verticale) che ha il suo massimo in 0;
per farti qualche esempio, in "AviSynth", l'algoritmo chiamato
"bilinear" e' definito da questa funzione:
double TriangleFilter::f(double x)
{  
  x = fabs(x);
  return (x<1.0) ? 1.0-x : 0.0;
}
la prima istruzione (x = fabs(x)) ha come conseguenza che la funzione
e' appunto pari; la seconda definisce il risultato: trattandosi solo
di un confronto e di una sottrazione, questo algoritmo risulta molto
veloce, ma anche poco accurato...
risultati piu' accurati sono ottenuti dalle funzioni "bicubic"
(o Mitchell-Netravali) e "lanczos", ma richiedono un maggior tempo
di calcolo: la prima e' un polinomio di terzo grado (richiede varie
moltiplicazioni), e la seconda richiede il calcolo di una funzione
trigonometrica;
pare che "lanczos" sia quella che "conserva maggiormente i dettagli";
a detta di alcuni, un'ulteriore funzione ("iperbolica") darebbe
risultati ancora piu' precisi, ma secondo me tra queste tre menzionate
non c'e' una gran differenza... naturalmente esistono molte altre
funzioni (ad esempio, una "gaussiana" del tipo f(x)=a^(-b*x^2)) ma
non so quanto siano buone...

  ha scritto:
Ti ringrazio di queste interessanti spiegazioni.
Ma quello che intendevo sapere  - scusami mi sono espresso davvero
male-  è se vi sono differenze in termini di resa qualitativa  tra  un
software  ed un altro.
Comunque, mi par di capire che il bicubic è sempre lo stesso qualunque
software si utilizzi e questo vale anche per gli altri algoritmi.
scusate forse sto facendo domande un po' troppo idiote :-)

 software si utilizzi e questo vale anche per gli altri algoritmi.
L'algoritmo base è sempre lo stesso, in un caso (almeno che io sappia)
cambiano i parametri. Sto pensando al bicubico.
A parità di algoritmo (bicubic) non si può dire a priori quale siano i
parametri migliori e di conseguenza non si può dire quale sia
l'implementazione migliore.
Esiste, però, un'implementazione in cui la scelta dei parametri è libera
equindi si adatta a qualsiasi esigenza. Questa implementazione la trovi in
avisynth. Per esempio
BicubicResize(480, 320, 0,0.75) è identico al bicubic di VirtualDub a
parità di risoluzione, ma nel primo caso puoi variare i valori 0 0.75 ed
inserire quelli più adatti alle tue esigenze.
Bye, Giubbe
-- 
HomePage e FAQ: 
http://giubbe.altervista.org
Inutile scrivere in privato, non ricevo le email

 inserire quelli più adatti alle tue esigenze.
intendi dire che, per ogni esigenza,  uno dovrebbe provare una coppia di
valori, poi un'altra coppia di valori diversi e confrontare (a occhio) i
risultati?
nell'articolo di Mitchell e Netravali sono discusse varie scelte di (B,C),
in particolare la figura 13 nella quarta pagina mostra 5 regioni per tutti
i possibili valori di (B,C) nel range [0,1]x[0,1]: quattro presentano
tipici difetti (nella penultima pagina sono mostrati degli esempi), mentre
quella centrale viene considerata "satisfactory"...

 risultati?
Esatto. Con la terminologia di GK
Sharp Bicubic   --> BicubicResize(x,y,0,0.75)
Soft Bicubic    --> BicubicResize(x,y,0.333,0.333)
Neutral Bicubic --> BicubicResize(x,y,0,0.5)


 Neutral Bicubic --> BicubicResize(x,y,0,0.5)
ah, ho capito.
in pratica ci si limita a provare solo poche coppie di valori ben precise...
pensavo che si dovesse procedere a tentoni su tutte le coppie possibili
(variando i parametri da 0 a 0.05, poi 0.1, 0.15, 0.2 ecc, si hanno 400
possibili coppie);
le coppie del tipo (0,C) definiscono curve che sono chiamate "cardinali",
in particolare il "Neutral Bicubic" e' anche nota come "Catmull-Rom spline";
stando a quanto ho letto, la coppia (0,0.75) e' quella che dovrebbe appunto
aumentare la sharpness, ma si trova proprio al limite (pericoloso) di un
brutto effetto collaterale chiamato "ringing"; ho visto che viene usato anche
(0,0.6) che sembra percio' una scelta piu' prudente;
anche la scelta (1/3,1/3) (cioe' Soft Bicubic) viene menzionata e riportata
come "un compromesso accettabile" tra blurring, ringing e anisotropy...
comunque, mi sono imbattuto in quest'altro articolo:
http://citeseer.ist.psu.edu/boult93local.html
di tali Boult e Wolder (il secondo e' quello del libro "Digital Image
Warping")
per ora ho letto solo l'abstract; mi pare di capire che questi abbiano
realizzato e studiato "metodi locali" che (a loro dire) danno risultati
migliori dei metodi piu' tradizionali, tra cui appunto il tipo di filtri
che usiamo noi per scalare quando facciamo i divx.
credo che il loro punto di partenza sia la definizione di un modello
matematico dell'effettivo processo di formazione delle immagini...
boh... mi sembra complicato :-)

come "un compromesso accettabile" tra blurring, ringing e anisotropy...
scusate l'intromissione, ma mi sono sempre chiesto se abbia un senso
ridimensionare, dato che si perde in qualità: non conviene lasciare
tutto com'è (aniso compreso) e regolare solo la compressione?
già la risoluzione di partenza è modesta, in genere è intorno
a 704x430! e il ridimensionamento del player che ingrandisce
l'immagine a video toglie un altro spicchio di dettaglio...
che ne pensate?
io in effetti faccio così, tanto le proporzioni le sistema
mediaplayer classic e uso solo il pc.
ciao

 a 704x430!
di solito e' 720x576, ma il problema e' che l'aspect ratio e' 16:9
e, se lascio il filmato a 720x576, il lettore stand-alone lo espande
a tutto schermo (mentre il dvd originale lo "schiaccia" in modo
corretto) e quindi si vede male (allungato)

 sono in molti a pensarla come te
Aggiungo che apparte altissimi bitrate, con una risoluzione così alta è
possibile che nelle scene più movimentate ci siano artefatti, per questo
si fanno anche dei test di comprimibilità del filmato.
Quindi se è molto comprimibile si sale di risoluzione, diciamo per avere
un ordine di misura 672*xxx o 704*xxx proprio se è un filmato
particolare mooolto comprimibile, altrimenti si rimane sui 640*xxx
608*xxx, arrivando tranquillamente anche a 576*xxx (o meno) in caso di
film poco comprimibili, oppure con bitrate bassi (film lunghetti su 1
cd).
Ovviamente per la comprimibilità influisce anche l'algoritmo di
resizing, quindi normalmente se un 640*xxx@lanczos richiede un maggiore
bitrate (per non creare artefatti) rispetto ad un 640*xxx@bicubicsoft.
Quindi se uno ad esempio verifica che a 640 un film si comprime bene,
può usare un filtro che lascia maggiori dettagli (quindi lanczos o
bicubic sharp ad esempio), oppure salire a 672 e rifare vari test con
vari filtri.
Ovviamente oltre ai valori bisogna vedere ad occhio, come mi ha sempre
suggerito Giubbe :)
Inoltre un filmato a 640 con un buon bitrate a tutto schermo non ha
problemi imho (visto su 19" oppure su tv normale).
Infine 720 non è divisibile per 32 e non ricordo che problemi ci
potessero essere, mi pare in qualche caso schede nvidia anche se non ho
mai avuto problemi personalmente. Magari il fatto che il lettore da TV
te li faccia a tutto schermo è dovuto proprio a quello....
-- 
Freccia@Bulldozer63 :D

 te li faccia a tutto schermo è dovuto proprio a quello....
no, il lettore stand-alone espande a tutto schermo perche' non e' stato
scritto bene; ti faccio un esempio:
prendo un DVD che contiene un film e un "contenuto speciale" (il "making
of"); entrambi i filmati sono mpeg2 720x576, ma il film ha un AR 16:9
mentre il secondo 4:3.
ebbene, i lettori per pc ridimensionano correttamente entrambi i filmati,
perche' leggono l'AR di ciascun filmato.
adesso ricodifico in divx entrambi i filmati senza scalarli, memorizzando
i rispettivi AR nello stream MPEG4; e' possibile farlo anche a posteriori
con l'utility Mpeg4modifier;
ebbene, anche con i divx, i lettori per pc ridimensionano correttamente
entrambi i filmati, perche' leggono l'AR di ciascun filmato (almeno,
mplayer lo fa automaticamente, e comunque, altri player, anche se non
lo fanno automaticamente, consentono comunque di impostare l'AR);
adesso passiamo al lettore stand-alone.
se metto il DVD, il lettore visualizza bene entrambi i filmati (cioe'
mette a schermo intero il "contenuto speciale" e "schiaccia" il film)
quindi evidentemente legge gli AR dei filmati MPEG2 e ne tiene conto;
se invece metto i due divx, il lettore non e' capace di distinguere
tra i due filmati e li visualizza entrambi a tutto schermo!
e' chiaro che il "contenuto speciale" si vede bene, ma il film
risulta "allungato"...

 te li faccia a tutto schermo è dovuto proprio a quello....
Concordo su tutto, tranne che qui dove c'è una lieve imperfezione (che
pignolo che sono ^_^). 
Il problema della divisione per 32 era di vecchie schede grafiche (matrox e
Nvidia) che con una risoluzione non adeguata non riuscivano ad agganciare
l'overlay. Questo dava problemi di performance e scadeva un poco la qualità
a seconda del lettore usato. Oggi, anche se rifacessero schede di questo
tipo, problemi di perfomance non ci sono e per il resize software (con
overlay è sempre il bilineare, in RGB dipende dal player) si può usare
ffdshow.


 
Quello che dici qua è il lavoro di previsione del programma enc (o simili)
e si usa proprio per non aspettare una codifica intera. Altrimenti
risulterebbe oltremodo lungo testare l'effetto di alcuni filtri.
Bye


 previsioni.
grazie :-) sto cercando di capire come posso farlo :-)
sto dando un'occhiata al codice di "enc"... forse sbaglio ma quello che
dici tu, cioe' la "scelta automatica per tutta la lunghezza del filmato"
viene fatta da questo pezzo nella "sub SP" (presumo che "SP" stia per
"Size Prediction"):
-----------------------------------
   # SelectRangeEvery
   if (!$all)
           {
           $data .= "\r\nSelectRangeEvery($tot,$ss)";
           }
   # Save file
   $ok = SaveFile($avs, ">", $data);
-----------------------------------
cioe', viene scritta l'istruzione "SelectRangeEvery" dentro a un file
che immagino sia uno script che verra' elaborato dal frame server
AviSynth (le mie sono semplici deduzioni, dato che non ho mai visto
ne' AviSynth ne' enc, ne' Virtualdub... sono un primitivo! :-) )
quindi, se ho ben capito, la scelta effettiva dei frame viene delegata
ad altro programma, che e' quello che eseguira' l'istruzione
"SelectRangeEvery"...
adesso vorrei capire come viene fatta tale scelta.
credo che tu intendessi dire che il 15% del filmato viene scelto in
modo uniforme su tutto il filmato, ma ancora mi sfugge un particolare.
facciamo un esempio.
supponiamo che un filmato abbia 100000 frames;
il 15% di 100000 e' 15000.
in pratica dovrei considerare in media un frame ogni 6.6666...
ma ovviamente non posso scegliere un frame isolato ogni 6-7 frames
di filmato perche' ho bisogno di fare un'analisi dei motion vectors
dei macroblocchi di un certo numero di frames *contigui*;
quindi, in realta', devo prima dividere 15000 in tanti "segmenti"
che siano abbastanza lunghi da consentire un'analisi significativa
dei motion vectors, e poi posso distribuire in modo uniforme tali
segmenti su tutto il filmato.
e' giusto?
e in tal caso, qual e' una lunghezza sensata per tali segmenti?

 e in tal caso, qual e' una lunghezza sensata per tali segmenti?
Con un filmato di un ora e 57 minuti e selezionando il 15% tira furori un
filmato da 17.53 con l'istruzione SelectRangeEvery(93,14)
L'instruzione indica di prendere 14 frame ogni 93 a partire da 0, cioè
prende 0-13 93-106 186-199 e così via.
bye


 prende 0-13 93-106 186-199 e cosě via.
sei stato chiarissimo.
la prima cosa che mi sono chiesto e' questa: perche' SelectRangeEvery(93,14)
e non invece SelectRangeEvery(100,15)?
in altre parole: andrebbe bene anche prendere 15 frame ogni 100 (che e'
precisamente il 15%) o c'e' qualche motivo per cui e' piu' sensato
prenderne 14 ogni 93?
la seconda osservazione e' che secondo me questa tecnica e' difettosa, e
adesso ti spiego perche'.
chiamiamo "filmato intero" quello da un'ora e 57 minuti, e "filmato breve"
quello di 17.53.
quando codifichiamo il filmato breve, il codec si vede arrivare i frame
0, 1, 2, ..., 13, 93, ...
quando gli arriva il 93 sicuramente genera un keyframe perche' il 93 non
e' quello veramente successivo al precedente, quindi e' praticamente certo
che rilevi un cambio di scena... e lo stesso accade con il 186 e con
tutti i multipli di 93;
se definiamo il "keyint medio" di un divx come il rapporto tra il numero
di tutti i frames e il numero dei keyframes, allora il keyint medio del
filmato breve sara' minore o uguale a 14.
ti torna?
pero' ci sono molti film in divx che hanno valori di keyint medio ben
piu' alti di 14; certi film "statici" possono arrivare anche a 80-90...
c'e' un legame molto stretto tra la comprimibilita' di un filmato e
il keyint medio di una codifica fatta ad alto bitrate (sebbene la
comprimibilita' sia influenzata anche da altre caratteristiche)
quello che voglio dire e' che, se il filmato lungo, codificato a
quantizer costante 2, raggiunge un keyint medio diciamo pari a 84, il
filmato breve ottiene un numero di keyframes ben 6 volte superiore a
quello che dovrebbe ottenere, quindi non mi pare affatto un campione
statisticamente rappresentativo per il filmato intero!
il problema nasce dal fatto che nel filmato breve abbiamo introdotto
dei "cambi di scena artificiali" (uno ogni 14 frames);
per rimediare a questo inconveniente, trovo piu' sensato usare un
approccio di questo tipo: SelectRangeEvery(1666,250)
perche' 250?
perche' e' il valore che di solito si usa come "max keyint" (10 volte
il framerate) ed e' il tetto massimo oltre il quale il codec
genererebbe comunque un keyframe...
per smorzare ancora piu' l'effetto dei "cambi di scena artificiali"
si possono usare valori anche piu' grandi di 250, per esempio
SelectRangeEvery(3333,500)
che ne pensi?
secondo me vale la pena fare qualche esperimento su queste cose...
pero' oggi non posso :-)

 genererebbe comunque un keyframe...
Qui sono d'accordo con te, però enc con il DivX 5.02 e con XviD<1 non
sbagliava un colpo (ora è un po' più elastico con XviD, non so con DivX) e
quindi presumo che Jonny abbia implementato un algoritmo di previsione che
tiene conto di queste obiezioni.
Io non ho controllato l'algoritmo, tu che dici? C'è qualcosa del genere?


 Io non ho controllato l'algoritmo, tu che dici? C'è qualcosa del genere?
forse si':
in pratica lui definisce queste variabili:
------------
        # % & snip size
        my $p   = $P->{CTP};
        my $ss  = 14;
        my $tot = int(100 * $ss / $p);
        my @map = (0, 13);
------------
$ss e' sempre 14, mentre $tot e' 100*$ss/$p; questo e' coerente con i valori
che hai riportato te:
- int(100*14/4) = 350
- int(100*14/23) = 60
ma quello che mi chiedo e': a cosa gli serve map?
le istruzioni successive sono queste:
------------
        # Extended method
        if ($P->{Met} eq "ex")
                {
                @map = (0, 1, 2, 11, 12, 13);
                }
------------
ma non ho idea di cosa significhi "metodo esteso";
la cosa interessante e' che dopo che e' stata effettuata la codifica,
map viene passata alla funzione LogSize che effettua dei conteggi,
analizzando riga per riga un logfile generato dalla codifica, e
penso che map venga utilizzata per conteggiare a parte i frame che
occupano quelle posizioni (cioe': 0, 13, 14, 27, 28, 41, 42, ecc);
pero' non ho capito cosa faccia dopo...
domani lo guardero' meglio; o scrivero' all'autore per avere qualche
ragguaglio...
ciao

 ragguaglio...
Poi facci sapere, sono curioso anch'io di capire come funziona.
Bye


 siano attivati i b-frame. (Vedi la documentazione sul sito).
ho letto quasi tutta la documentazione e ho guardato un po' meglio
il programma;
credo di avere capito cosa fa, piu' meno :-)
sintetizzando al massimo, una volta effettuata la codifica del
filmato breve (con "SelectRangeEvery(...,14)") a qualita' costante
(quantizer 2), analizza il logfile che e' stato generato durante
la codifica; tale logfile contiene una riga per ciascun frame
encodato, il programma analizza ogni riga estraendo la dimensione
in bytes di quel frame, e ne calcola la somma totale; pero'...
(e questo e' il punto cruciale) scarta tutti i frame che hanno
l'indice "congruo modulo 14" a un elemento contenuto in map;
quindi, se map=(0,13) (metodo normale), i frames scartati sono
0,13,14,27,28,41,42,55,56, ecc
se invece map=(0,1,2,11,12,13) (metodo esteso, cioe' XviD con
b-frames), allora scarta questi frames:
0,1,2,11,12,13,14,15,16,25,26,27,28,29,30, ecc
il programma dovrebbe generare un suo logfile da qualche parte,
nel quale si dovrebbero vedere i frame scartati che sono
contrassegnati con la stringa "[D]" (forse sta per "discarded")
chiaramente, se uno chiede di fare il test sul 100% del film,
questo caso viene trattato in modo diverso, e non scarta alcun
frame...
credo che in questo modo dovrebbe evitare il problema dei "cambi
di scena introdotti artificialmente" di cui parlavo ieri...
pero' mi sfuggono ancora alcuni particolari sul perche' faccia
proprio in quel modo; e in particolare, perche' nel caso di
XviD con b-frames non usa sequenze piu' grandi di 14? in
pratica, butta via quasi la meta' delle informazioni ottenute
da cio' che codifica... se usasse sequenze piu' lunghe, ci
sarebbe molto meno spreco;
se mi viene in mente qualcos'altro ti faro' sapere
ciao

 ciao
Sempre contento di leggerti.


corretto) e quindi si vede male (allungato)
beh il problema dello schiacciamento se non si può correggere
è grave, ma io guardo solo su pc.
del resto credo che la tv sia di troppo scarsa risoluzione per
preoccuparsi del ridimensionamento :)
ciao

 è grave, ma io guardo solo su pc.
in realta', uno dei miei televisori ha l'opzione "16:9" che ha
appunto l'effetto di "schiacciare" lo schermo (inserire due bande
orizzontali sopra e sotto), quindi su quello potrei vederli bene;
ma gli altri televisori non hanno tale possibilita'...
il problema e' che tale schiacciamento dovrebbe farlo il lettore!
invece con i DivX si comporta in modo molto rigido: e' lui che
decide (in base a un suo algoritmo) quale sia l'AR del filmato e
non da' alcuna possibilita' di impostare un AR diverso...
non e' un problema di limitazioni hardware, lo stesso lettore e'
capace di rispettare l'AR dei file mpeg2; e' solo pigrizia di chi
ha scritto il firmware, che si e' semplificato la vita al massimo
(e l'ha complicata agli utilizzatori :-))

un'opzione "16:9"?
mediaplayer classic ha l'opzione 16/9 ed anche altre,
inoltre è possibile personalizzare l'a/r e lo zoom.
I film che ho visto io, hanno tutti lo stesso ar
nonostante alcuni siano in 16/9, altri in 2.35/1 ed altri in 4/3.
questo perchè a quanto ho capito un film in 4/3 usa tutte le 576
linee, uno in 16/9 ne usa circa 420, uno in 2.35/1 ancora meno.
Per cui in pratica l'ar, essendo indipendente dal cropping, è sempre
lo stesso, e il dvd player non deve indovinarlo.
Questa è la mia esperienza perlomeno.
ciao

 lo stesso, e il dvd player non deve indovinarlo.
non proprio :-)
quando croppi cambi l'AR... e' proprio non croppando che l'AR e'
fisso (16:9 o 4:3);
ma se tu croppi, per fare un esempio, selezionando una regione
704x400 (da un'area 720x576), e l'AR iniziale e' 16:9, l'AR del
nuovo filmato diventa:
(16/9)*(704/400)*(576/720) = (circa) 2.5:1
a questo punto le possibilita' sono 3:
1) oltre a croppare, effettui anche uno scaling, in modo tale che
   l'AR calcolato sia esattamente il rapporto tra larghezza e
   altezza del filmato scalato (ad esempio, potresti scalare a
   704x282, dato che 704/282 = (circa)2.5, e in tal modo ottieni
   un filmato correttamente proporzionato, che piace anche ai
   lettori stand-alone)
2) memorizzi l'AR nel filmato stesso; ci sono due posti in cui si
   puo' memorizzare tale informazione: nello stream mpeg4 (lo puo'
   fare anche l'utility mpeg4modifier) oppure in un header ODML;
   purtroppo nessuno di questi modi viene rispettato dai lettori
   stand-alone; pero' vengono rispettati da alcuni lettori per pc
3) usi un lettore per pc che sia abbastanza astuto da ipotizzare
   che quel filmato e' il cropping di un filmato 720x576 e quindi
   sia capace di ricalcolarsi il corretto AR 2.5:1


sì sì hai ragione, intendevo dire che quando croppo un 720x576
ad esempio a 704x426 la trasformazione è sempre la stessa,
cioè per ottenere l'immagine corretta devo allargare X e Y
dello stesso identico fattore, ecco perchè con film con diverse
risoluzioni mi basta un unico comando in mediaplayerclassic
per raddrizzarli alla perfezione! (ovviamente se e solo se sono in 4/3
li vedo bene subito)
ciao!

si fanno anche dei test di comprimibilità del filmato.
in genere non imposto affatto il bitrate: setto quality 2.0 in xvid...
ciao

 li vedo bene subito)
si', il fattore e' sempre lo stesso.
in realta', anche un dvd 4:3 andrebbe "trasformato": se il tuo monitor
e' regolato bene, guardando un dvd 4:3 in una finestra 720x576 lo
dovresti vedere leggermente allungato verso l'alto;
per regolare il monitor, basta che tu visualizzi un'immagine che
contiene un quadrato perfetto (con lati che hanno lo stesso numero
di pixel) e regoli altezza e larghezza in modo che venga visualizzato
un quadrato perfetto;
un dvd 4:3 andrebbe visualizzato in una finestra 768x576 o
proporzionale;
il comando di MPC di cui parli tu, forse applica un fattore di
correzione di 4/3 (e' quello che fa il mio televisore con
l'opzione "16:9": "schiaccia" lo schermo riducendone l'altezza del
75% e aggiunge un bordo sopra e sotto: questo equivale a moltiplicare
l'aspect ratio per 4/3);
in realta', il fattore da applicare sarebbe (16/9)*(576/720);
se pero' approssimiamo 576/720 (=4/5) con 3/4, il fattore diventa
(16/9)*(3/4)=4/3.
facendo questa approssimazione, si ottiene un risultato "accettabile",
in fondo il rapporto tra 5/4 e 4/3 e' 15/16=~0.937
e la differenza non si nota facilmente...

correzione di 4/3 (e' quello che fa il mio televisore con
in realtà ha sia 4/3 che 16/9 ed inoltre è possibile aggiungerne
altri personalizzati a piacere :)
ciao