Seconda parte:
Qualsiasi raster immagine può essere rappresentata sotto forma di matrice bidimensionale. Quando si parla di colori, l'idea può essere sviluppata considerando l'immagine come una matrice tridimensionale, in cui le dimensioni aggiuntive vengono utilizzate per memorizzare i dati per ciascuno dei colori.
Se consideriamo il colore finale come una combinazione dei cosiddetti colori primari (rosso, verde e blu), nella nostra matrice tridimensionale definiamo tre piani: il primo per il colore rosso, il secondo per il verde e l'ultimo per il blu.
Ogni punto in questa matrice sarà chiamato pixel (elemento dell'immagine). Ogni pixel contiene informazioni sull'intensità (di solito sotto forma di valore numerico) di ciascun colore. Ad esempio, un pixel rosso significa che contiene 0 verde, 0 blu e il massimo di rosso. Un pixel di colore rosa può essere formato da una combinazione dei tre colori. Utilizzando un intervallo numerico da 0 a 255, un pixel rosa è definito come Rosso = 255, Verde = 192 e Blu = 203.
L'articolo è stato pubblicato con il supporto della compagnia EDISON.Sviluppiamo , e ci occupiamo anche di .
Metodi alternativi di codifica delle immagini a colori
Per rappresentare i colori di cui è composta l'immagine, esistono molte altre modelli. Ad esempio, è possibile utilizzare una palette indicizzata, in cui è necessario solo un byte per rappresentare ogni pixel, invece dei tre necessari utilizzando il modello RGB. In tale modello, è possibile utilizzare una matrice 2D invece di una matrice 3D per rappresentare ciascun colore. Questo risparmia memoria, ma offre una gamma di colori inferiore.

RGB
Ad esempio, guarda questa immagine qui sotto. Il primo volto è completamente colorato. Gli altri sono i piani rosso, verde e blu (l'intensità dei colori corrispondenti è mostrata in scala di grigi).

Si vede che le tonalità di rosso nell'originale saranno negli stessi punti in cui si osservano le parti più luminose del secondo volto. Mentre il contributo del colore blu può essere visto principalmente solo negli occhi di Mario (l'ultimo volto) e negli elementi dei suoi vestiti. Nota dove tutti e tre i piani di colore contribuiscono meno (le parti più scure delle immagini) — ciò avviene nei baffi di Mario.
Per memorizzare l'intensità di ogni colore è necessario un certo numero di bit: questa quantità è chiamata profondità di bit. Supponiamo di usare 8 bit (con valori da 0 a 255) per un piano colore. Avremo quindi una profondità di colore di 24 bit (8 bit * 3 piani R/G/B).
Un'altra proprietà dell'immagine è la risoluzione, che rappresenta il numero di pixel in una dimensione. Spesso viene indicata come larghezza × altezza, come nel seguente esempio di immagine 4 su 4.

Un'altra proprietà con cui abbiamo a che fare quando lavoriamo con immagini/video è il rapporto d'aspetto, che descrive la consueta relazione proporzionale tra la larghezza e l'altezza dell'immagine o del pixel.
Quando si dice che un certo film o immagine ha una dimensione di 16 su 9, di solito ci si riferisce al rapporto d'aspetto del display (DAR — da Display Aspect Ratio). Tuttavia, talvolta possono esistere forme diverse dei singoli pixel: in questo caso si parla di rapporto dei pixel (PAR — da Pixel Aspect Ratio).


Nota per la padrona di casa: DVD corrisponde a DAR 4 su 3
Sebbene la risoluzione reale del DVD sia 704×480, mantiene comunque un rapporto d'aspetto di 4:3, poiché il PAR ha un valore di 10:11 (704×10 / 480×11).
E infine, possiamo definire video come una sequenza di n fotogrammi per periodo di tempo, che può essere considerato una dimensione aggiuntiva. E n allora - questa è la frequenza dei fotogrammi o il numero di fotogrammi al secondo (FPS — da Frames per Second).

Il numero di bit al secondo necessari per visualizzare un video è la sua — velocità di trasmissione.
bitrate = larghezza * altezza * profondità di bit * fotogrammi al secondo
Ad esempio, per un video con 30 fotogrammi al secondo, 24 bit per pixel e risoluzione 480×240 saranno necessari 82.944.000 bit al secondo o 82,944 Mbit/s (30x480x240x24) - ma ciò vale se non viene utilizzato alcun metodo di compressione.
Se la velocità di trasmissione è quasi costante, viene chiamata velocità di trasmissione costante (CBR — da constant bit rate). Tuttavia, può anche variare, in questo caso viene chiamata velocità di trasmissione variabile (VBR — da variable bit rate).
Questo grafico dimostra un VBR limitato, quando non vengono sprecati troppi bit in caso di un fotogramma completamente scuro.

Inizialmente, gli ingegneri hanno sviluppato un metodo per raddoppiare la frequenza percepita dei fotogrammi del video senza utilizzare banda aggiuntiva. Questo metodo è conosciuto come video interlacciato; principalmente, invia metà dello schermo nel primo "fotogramma", mentre l'altra metà nel successivo "fotogramma".
Attualmente, la visualizzazione delle scene avviene principalmente utilizzando la tecnologia di scansione progressiva. Questo è un modo di visualizzare, memorizzare o trasmettere immagini in movimento, in cui tutte le linee di ciascun fotogramma vengono tracciate in sequenza.

Bene! Ora sappiamo come un'immagine viene rappresentata digitalmente, come sono strutturati i suoi colori, quanti bit al secondo utilizziamo per mostrare il video, se la velocità di trasmissione è costante (CBR) o variabile (VBR). Siamo a conoscenza della risoluzione impostata utilizzando una frequenza fotogrammi predeterminata e ci siamo familiarizzati con molti altri termini, come video interlacciato, PAR e altri.
Eliminazione della ridondanza
È noto che è impossibile utilizzare video non compressi normalmente. Un'ora di video a risoluzione 720p e 30 fotogrammi al secondo occuperebbe 278 GB. Raggiungiamo questo valore moltiplicando 1280 x 720 x 24 x 30 x 3600 (larghezza, altezza, bit per pixel, FPS e tempo in secondi).
Utilizzo algoritmi di compressione senza perdita, come DEFLATE (utilizzato in PKZIP, Gzip e PNG), non darà una riduzione sufficiente della larghezza di banda necessaria. Dobbiamo cercare altri modi per comprimere il video.
Per farlo, possiamo utilizzare le caratteristiche della nostra visione. Siamo più sensibili alla luminosità che ai colori. Il video è un insieme di immagini sequenziali che si ripetono nel tempo. Tra i fotogrammi adiacenti di una scena, le differenze sono minime. Inoltre, ciascun fotogramma contiene molte aree che utilizzano lo stesso (o un colore simile).
Colore, luminosità e i nostri occhi
I nostri occhi sono più sensibili alla luminosità che al colore. Puoi verificarlo tu stesso guardando questa immagine.

Se non noti che nella metà sinistra dell'immagine i colori dei quadrati A e B sono effettivamente identici, va bene. Il nostro cervello ci porta a prestare maggiore attenzione alla luce e all'ombra, piuttosto che al colore. A destra, tra i quadrati segnalati, c'è un collegamento dello stesso colore — quindi noi (cioè il nostro cervello) rileviamo facilmente che, in effetti, è lo stesso colore.
Analizziamo (in modo semplificato) come funzionano i nostri occhi. L'occhio è un organo complesso, composto da molte parti. Tuttavia, ciò che ci interessa di più sono i coni e i bastoncelli. L'occhio contiene circa 120 milioni di bastoncelli e 6 milioni di coni.
Consideriamo la percezione del colore e della luminosità come funzioni separate di determinate parti dell'occhio (in realtà, la situazione è un po' più complessa, ma semplifichiamo). Le cellule dei bastoncelli rispondono principalmente alla luminosità, mentre le cellule dei coni rispondono al colore. I coni sono suddivisi in tre tipi, a seconda del pigmento presente: coni S (colore blu), coni M (colore verde) e coni L (colore rosso).
Poiché abbiamo molti più bastoncelli (luminosità) che coni (colore), si può dedurre che siamo più capaci di distinguere i passaggi tra oscurità e luce piuttosto che i colori.
Funzioni di sensibilità al contrasto
I ricercatori di psicologia sperimentale e di molti altri campi hanno sviluppato numerose teorie sulla visione umana. E una di esse si chiama funzioni di sensibilità al contrasto. Queste sono collegate all'illuminazione spaziale e temporale. In breve, si tratta di quanti cambiamenti sono necessari prima che l'osservatore li noti. Nota il plurale della parola “funzione”. Questo è dovuto al fatto che possiamo misurare le funzioni di sensibilità al contrasto non solo per immagini in bianco e nero, ma anche per immagini a colori. I risultati di questi esperimenti mostrano che, nella maggior parte dei casi, i nostri occhi sono più sensibili alla luminosità rispetto al colore.
Dato che è noto che siamo più sensibili alla luminosità dell'immagine, si può cercare di sfruttare questo fatto.
Modello di colore
Abbiamo imparato un po' su come gestire le immagini a colori usando lo schema RGB. Esistono anche altri modelli. Ce n'è uno che separa la luminosità dalla cromaticità ed è conosciuto come YCbCr. A proposito, ci sono anche altri modelli che fanno una divisione simile, ma noi considereremo solo questo.
In questo modello di colore Y — è la rappresentazione della luminosità, e sono utilizzati due canali di colore: Cb (blu intenso) e Cr (rosso intenso). YCbCr può essere ottenuto da RGB, così come è possibile anche la conversione inversa. Utilizzando questo modello, possiamo creare immagini a colori, come vediamo di seguito:

Conversione tra YCbCr e RGB
Qualcuno potrebbe obiettare: come è possibile ottenere tutti i colori, se non viene utilizzato il verde?
Per rispondere a questa domanda, convertiamo RGB in YCbCr. Utilizzeremo i coefficienti stabiliti negli standard BT.601, raccomandato dal dipartimento ITU-R. Questo dipartimento definisce gli standard per il video digitale. Ad esempio: cosa significa 4K? Quali dovrebbero essere la frequenza dei fotogrammi, la risoluzione, il modello di colore?
Iniziamo a calcolare la luminosità. Utilizziamo le costanti proposte dall'ITU e sostituiamo i valori RGB.
Y = 0.299R + 0.587G + 0.114B
Dopo aver ottenuto la luminosità, separiamo il blu e il rosso:
Cb = 0.564(B — Y)
Cr = 0.713(R — Y)
E possiamo anche convertire indietro e persino ottenere il verde utilizzando YCbCr:
R = Y + 1.402Cr
B = Y + 1.772Cb
G = Y — 0.344Cb — 0.714Cr
In generale, i display (monitor, TV, schermi, ecc.) utilizzano solo il modello RGB. Ma questo modello può essere organizzato in modi diversi:

Sottocampionamento del colore
Con un'immagine rappresentata come una combinazione di luminosità e crominanza, possiamo sfruttare la maggiore sensibilità del sistema visivo umano alla luminosità rispetto alla crominanza, se rimuoviamo selettivamente le informazioni. Il sottocampionamento del colore è un metodo di codifica delle immagini, utilizzando una risoluzione inferiore per la crominanza rispetto alla luminosità.

Quanto è accettabile ridurre la risoluzione della crominanza?! Si scopre che ci sono già alcuni schemi che descrivono come gestire la risoluzione e la fusione (Colore finale = Y + Cb + Cr).
Questi schemi sono noti come sistemi di sottocampionamento e vengono espressi in forma di rapporto 3:1 — a:x:y, che definisce il numero di campioni di segnali di luminosità e differenza di colore.
a — campionamento orizzontale di riferimento (di solito uguale a 4)
x — numero di campioni di crominanza nella prima riga di pixel (risoluzione orizzontale rispetto a a)
y — numero di cambiamenti di campioni di crominanza tra la prima e la seconda riga di pixel.
L'eccezione è 4:1:0, che fornisce un campione di crominanza in ogni blocco di risoluzione di luminosità 4 su 4.
Schemi comuni utilizzati nei codec moderni:
- 4:4:4 (senza sottocampionamento)
- 4:2:2
- 4:1:1
- 4:2:0
- 4:1:0
- 3:1:1
YCbCr 4:2:0 — esempio di fusione
Questo è un frammento dell'immagine unito utilizzando YCbCr 4:2:0. Si noti che utilizziamo solo 12 bit per pixel.
Ecco come appare la stessa immagine codificata con i principali tipi di sottocampionamento dei colori. La prima riga è YCbCr finale, la riga inferiore mostra la risoluzione della crominanza. Risultati piuttosto degni, considerando le piccole perdite di qualità.

Ricordate che abbiamo considerato 278 GB di spazio su disco per memorizzare un file video di un'ora a risoluzione 720p e 30 fotogrammi al secondo? Se utilizziamo YCbCr 4:2:0, questa dimensione si ridurrà della metà: 139 GB. Finora siamo ancora lontani da un risultato accettabile.
Potete ottenere un istogramma YCbCr usando FFmpeg. In questa immagine, il blu prevale sul rosso, come è chiaramente visibile nell'istogramma.

Crominanza, luminanza, gamma di colori - video panoramica
Si consiglia di guardare questo fantastico video. Qui viene spiegato cos'è la luminanza e sono chiariti tutti i punti sulla è luminanza e colore.
Tipi di fotogrammi
Andiamo avanti. Proviamo a eliminare la ridondanza temporale. Ma prima, definiamo una certa terminologia di base. Supponiamo di avere un film con 30 fotogrammi al secondo, eccoli i suoi primi 4 fotogrammi:

Possiamo vedere molte ripetizioni nei fotogrammi: per esempio, uno sfondo blu che non cambia da un fotogramma all'altro. Per risolvere questo problema, possiamo classificarli astrattamente in tre tipi di fotogrammi.
I-frame (Intro Frame)
L'I-frame (fotogramma chiave, fotogramma di riferimento, fotogramma interno) è autonomo. Indipendentemente da ciò che deve essere visualizzato, l'I-frame è essenzialmente una fotografia statica. Il primo fotogramma è solitamente un I-frame, ma ci aspettiamo di osservare I-frame anche tra fotogrammi non necessariamente all'inizio.

P-frame (Predicted Frame)
Il P-frame (fotogramma previsto) sfrutta il fatto che quasi sempre l'immagine attuale può essere riprodotta utilizzando il fotogramma precedente. Ad esempio, nel secondo fotogramma l'unica modifica è la palla che si muove in avanti. Possiamo ottenere il fotogramma 2 semplicemente modificando un po' il fotogramma 1, utilizzando solo la differenza tra questi fotogrammi. Per costruire il fotogramma 2 ci riferiamo al fotogramma precedente, il fotogramma 1.
← 
B-frame (Bi-predictive Frame)
E che dire dei riferimenti non solo ai fotogrammi passati, ma anche a quelli futuri, per garantire una compressione ancora migliore?! Questo è, in sostanza, il B-frame (fotogramma bidirezionale).
←
→ 
Output intermedio
Questi tipi di fotogrammi sono utilizzati per garantire la migliore compressione. Esamineremo come avviene, nella prossima sezione. Ma per ora, notiamo che il fotogramma I è il più "costoso" in termini di memoria utilizzata, il fotogramma P è notevolmente più economico, mentre il B-frame è l'opzione più vantaggiosa per il video.

Ridondanza temporale (previsione inter-frame)
Consideriamo quali possibilità abbiamo per minimizzare le ripetizioni nel tempo. Questo tipo di ridondanza lo risolviamo mediante metodi di previsione reciproca.
Cerchiamo di spendere il minor numero possibile di bit per codificare la sequenza di fotogrammi 0 e 1.

Possiamo effettuare una sottrazione, semplicemente sottraendo il fotogramma 1 dal fotogramma 0. Otteniamo il fotogramma 1, utilizzando solo la differenza tra di esso e il fotogramma precedente, codificando effettivamente solo il resto risultante.

Ma cosa succede se ti dico che c'è un metodo ancora migliore, che utilizza ancora meno bit?! Innanzitutto, dividiamo il fotogramma 0 in una griglia chiara composta da blocchi. E poi cerchiamo di abbinare i blocchi del fotogramma 0 con il fotogramma 1. In altre parole, valutiamo il movimento tra i fotogrammi.
Da Wikipedia — compensazione del movimento a blocchi
La compensazione del movimento a blocchi divide il fotogramma corrente in blocchi non sovrapposti e i vettori di compensazione del movimento indicano l'origine dei blocchi (un comune equivoco è che il fotogramma precedente sia suddiviso in blocchi non sovrapposti e i vettori di compensazione del movimento indichino dove si spostano questi blocchi. In realtà è il contrario: si analizza non il fotogramma precedente, ma quello successivo, si scopre non dove si spostano i blocchi, ma da dove sono arrivati). Di solito, i blocchi originali si sovrappongono nel fotogramma originale. Alcuni algoritmi di compressione video ricompongono il fotogramma corrente da parti di più fotogrammi precedentemente trasmessi.

Nel processo di valutazione, vediamo che la sfera si è spostata da (x=0, y=25) a (x=6, y=26), valori x e y definiscono la direzione del movimento. Un altro passo che possiamo compiere per conservare i bit è codificare solo la differenza dei vettori di movimento tra l'ultima posizione del blocco e quella prevista, quindi il vettore finale di movimento sarà (x=6-0=6, y=26-25=1).
In una situazione reale, questa sfera sarebbe suddivisa in n blocchi, ma non cambia il senso della questione.
Gli oggetti nell'inquadratura si muovono in tre dimensioni, quindi mentre la sfera si muove può apparire visivamente più piccola (o più grande se si avvicina allo spettatore). È normale che non ci sia corrispondenza perfetta tra i blocchi. Ecco una vista combinata della nostra stima e dell'immagine reale.

Ma vediamo che quando applichiamo la stima del movimento, i dati per la codifica sono notevolmente inferiori rispetto all'uso di un metodo più semplice per calcolare la delta tra i fotogrammi.

Come apparirà la compensazione del movimento
Questa metodologia viene applicata a tutti i blocchi. Spesso la nostra sfera in movimento sarà subito suddivisa in più blocchi.

Puoi toccare tu stesso questi concetti utilizzando .
Per vedere i vettori di movimento si può creare un video con una previsione esterna utilizzando .

Puoi anche utilizzare (è a pagamento, ma c'è una versione di prova gratuita limitata solo ai primi dieci fotogrammi).

Ridondanza spaziale (previsione interna)
Se analizziamo ogni fotogramma del video, scopriremo molte aree interconnesse.

Esaminiamo questo esempio. Questa scena è principalmente composta da colori blu e bianco.

Questo è il fotogramma I. Non possiamo prendere i fotogrammi precedenti per la previsione, ma possiamo comprimerlo. Codificheremo la selezione del blocco rosso. Se guardiamo i suoi vicini, notiamo che ci sono alcune tendenze cromatiche attorno a esso.

Supponiamo che nel fotogramma i colori si diffondano verticalmente. Questo significa che i colori dei pixel sconosciuti conterranno valori dei loro vicini.

Questa previsione potrebbe rivelarsi errata. Proprio per questo motivo è necessario applicare questo metodo (previsione interna), e poi sottrarre i valori reali. Questo ci darà un blocco residuo, il che porterà a una matrice molto più compressa rispetto all'originale.

Se desideri esercitarti con le previsioni interne, puoi creare un video con i macroblocchi e le loro previsioni utilizzando ffmpeg. Per capire il significato di ogni colore del blocco, dovrai consultare la documentazione di ffmpeg.

In alternativa, puoi utilizzare Intel Video Pro Analyzer (come ho già menzionato sopra, la versione di prova gratuita ha un limite sui primi 10 fotogrammi, ma ti basterà per iniziare).

Seconda parte:
Fonte: habr.com



