2015-05-01 14 views
9

Non c'è alcuna biiezione tra RGB e Parula, discussa here. Sto pensando come fare bene l'elaborazione delle immagini dei file in Parula. Questa sfida è stata sviluppata da questo thread sulla rimozione del colore nero dalle immagini ECG estendendo il caso a un problema generalizzato con i colori Parula.Per riprodurre l'immagine Parula in Matlab senza perdere la risoluzione

dati:

enter image description here

che è generato da

[X,Y,Z] = peaks(25); 
imgParula = surf(X,Y,Z); 
view(2); 
axis off; 

Non è il punto di questa discussione per utilizzare questo codice nella soluzione di leggere la seconda immagine.

Codice:

[imgParula, map, alpha] = imread('http://i.stack.imgur.com/tVMO2.png'); 

dove map è [] e alpha è un'immagine completamente bianca. Facendo imshow(imgParula)

enter image description here

dove si vede un sacco di interferenze e perdita di risoluzione perché Matlab legge le immagini come RGB, anche se la mappa dei colori reale è Parula. Il ridimensionamento di questa immagine non migliora la risoluzione.

Come si può leggere l'immagine nella colormap corrispondente in Matlab? Non ho trovato alcun parametro per specificare la mappa di colori in lettura.

+0

Non è completamente chiaro per me: vuoi recuperare la matrice che è stata utilizzata per creare la prima immagine (con 'imshow' e la colormap parula)? – Ratbert

+0

Sì. Voglio recuperare i dati che sono stati utilizzati per creare la prima immagine Parula.Voglio essere in grado di creare la prima immagine leggendo il file di nuovo in Matlab e quindi tracciarlo di nuovo. –

+1

OK. Se non sai quale sia stata l'impostazione di 'caxis '(_i.e._intervallo del colormap) c'è un'indeterminazione. Ad esempio, il blu potrebbe essere qualsiasi valore in base a questa impostazione ... Una soluzione ti darebbe una matrice compresa tra 0 e 1, ad esempio, che potrebbe non essere l'intervallo di dati iniziale. – Ratbert

risposta

9

Il problema

C'è un one-to-one mapping dai colori indicizzati nel parula colormap a triplette RGB. Tuttavia, non esiste una mappatura one-to-one per invertire questo processo per convertire un colore indicizzato parula in RGB (in effetti ci sono un numero infinito di modi per farlo). Pertanto, non esiste una corrispondenza uno-a-uno o bijection tra i due spazi. La trama seguente, che mostra i valori R, G e B per ciascun indice parula, rende questo più chiaro.

Parula to RGB plot

Questo è il caso per colori più indicizzati. Qualsiasi soluzione a questo problema sarà non unica.


un built-in Solution

io dopo aver giocato in giro con questo un po ', mi sono reso conto che c'è già una funzione built-in che può essere sufficiente: rgb2ind, che converte i dati di immagine RGB in indicizzati dati di immagine. Questa funzione utilizza dither (che a sua volta chiama la funzione mex ditherc) per eseguire la trasformazione inversa della mappa di colori.

Ecco una dimostrazione che utilizza la compressione JPEG per aggiungere rumore e distorcere i colori nei dati parula indice originale:

img0 = peaks(32);      % Generate sample data 
img0 = img0-min(img0(:)); 
img0 = floor(255*img0./max(img0(:))); % Convert to 0-255 
fname = [tempname '.jpg'];   % Save file in temp directory 
map = parula(256);     % Parula colormap 
imwrite(img0,map,fname,'Quality',50); % Write data to compressed JPEG 
img1 = imread(fname);     % Read RGB JPEG file data 

img2 = rgb2ind(img1,map,'nodither'); % Convert RGB data to parula colormap 

figure; 
image(img0);       % Original indexed data 
colormap(map); 
axis image; 

figure; 
image(img1);       % RGB JPEG file data 
axis image; 

figure; 
image(img2);       % rgb2ind indexed image data 
colormap(map); 
axis image; 

Questo dovrebbe produrre immagini simili ai primi tre di seguito.

Example original data and converted images


Soluzione alternativa: differenza cromatica

Un altro modo per eseguire questa operazione è confrontando la differenza tra i colori dell'immagine RGB con i valori RGB che corrispondono a ciascun indice colormap . Il modo standard per farlo è calculating ΔE nello spazio colore CIE L*a*b*. Ho implementato una forma di questo in una funzione generale denominata rgb2map che può essere downloaded from my GitHub. Questo codice si basa su makecform e applycform in Image Processing Toolbox per convertire da RGB allo spazio colore CIE L * a * b * del 1976.

Il codice seguente produrrà un'immagine come quella qui sopra a destra:

img3 = rgb2map(img1,map); 

figure; 
image(img3);       % rgb2map indexed image data 
colormap(map); 
axis image; 

Per ogni pixel RGB un'immagine in ingresso in, rgb2map calcola la differenza di colore fra essa e ogni tripletta RGB nella mappa colori ingresso utilizzando lo standard CIE 1976. La funzione min viene utilizzata per trovare l'indice del minimo Δ E (se esiste più di un valore minimo, viene restituito l'indice del primo). Mezzi più sofisticati possono essere usati per selezionare il colore "migliore" nel caso di più Δ E minimo, ma saranno più costosi.


Conclusioni

Come esempio finale, ho usato an image of the namesake Parula bird di confrontare i due metodi nella figura seguente. I due risultati sono abbastanza diversi per questa immagine. Se modifichi manualmente rgb2map per utilizzare lo standard di differenza di colore più complesso CIE 1994, otterrai un altro rendering. Tuttavia, per le immagini che corrispondono più strettamente alla colormap originale parula (come sopra) entrambe dovrebbero restituire risultati più simili. È importante sottolineare che i vantaggi di rgb2ind derivano dal chiamare le funzioni mex e sono quasi 100 volte più veloci di rgb2map nonostante diverse ottimizzazioni nel mio codice (se si utilizza lo standard CIE 1994, è circa 700 volte più veloce).

RGB image of bird converted using two methods

Infine, coloro che vogliono saperne di più su mappe di colori in Matlab, dovrebbe leggere questo four-part MathWorks blog post da Steve Eddins sul nuovo parula mappa di colori.

Aggiornamento 6-20-2015:rgb2map codice sopra descritto aggiornato per utilizzare diverse trasformazioni dello spazio colore, che migliora la sua velocità di quasi un fattore due.

+0

'rgb2map' sembra essere migliore dell'occhio di' rgb2ind' in tutti i colori. 'rgb2map' sembra bruciare con il colore giallo. ** Perché questa masterizzazione si verifica in 'rgb2map'? Un modo per evitarlo? ** - Un'altra speranza è che se tu potessi mantenere la griglia delle linee verticali e orizzontali in alcuni dei tuoi esempi. Mi piacerebbe vedere come diverse funzioni influenzano le linee in diversi ambienti. Queste linee sono particolarmente messe lì per la sfida per una ragione particolare. –

+1

@Masi: Immagino che sia dovuto all'uso di una semplice funzione 'min' per trovare la corrispondenza dei colori più vicina. All'estremità, cioè vicino ai colori nero, bianco e completamente saturi, è probabile che ci saranno più minimi, nel qual caso verrà usato il primo. Ciò si traduce in molti pixel che appaiono come uno dei valori estremi sulla mappa dei colori. Metodi possibili attorno a questo: 1) riordinare la mappa dei colori in modo da selezionare sempre un diverso colore, 2) scegliere casualmente (o un altro schema) quando sono presenti più minimi, 3) usare la ponderazione per forzare determinati canali o combinazioni di essi per variare la scelta. – horchler

+1

La mappa colori 'parula' non include il bianco e il nero. Le tue immagini sembrano essere schermate e hanno linee nere nonostante l'uso di colori indicizzati perché stai visualizzando i dati non come un'immagine, ma come oggetto 3-D tramite 'surf' (il nero è il colore del bordo predefinito indipendentemente dai dati) . Un trattamento completamente diverso o casi speciali saranno necessari per gestire questo. Sarebbe forse meglio evitare il problema in primo luogo pre-elaborando e salvando i file in modo diverso. – horchler

Problemi correlati