2015-07-31 13 views
7

Ho questo codice MATLAB per visualizzare oggetto immagine dopo fare super-spettrogramma (STFT, paio PLCA ...)Armadillo porting imagesc per salvare l'immagine bitmap dalla matrice

t = z2 *stft_options.hop/stft_options.sr; 
f = stft_options.sr*[0:size(spec_t,1)-1]/stft_options.N/1000; 

max_val = max(max(db(abs(spec_t)))); 
imagesc(t, f, db(abs(spec_t)),[max_val-60 max_val]); 

E ottenere questo risultato:

enter image description here

ero porting su C++ con successo utilizzando Armadillo lib e ottenere i risultati opachi:

mat f,t,spec_t; 

Il problema è che non ho alcuna idea per la conversione di bitmap come imagesc in MATLAB.

Ho cercato e trovato this answer, ma sembra che non funziona nel mio caso perché:

  • Io uso una doppia matrice, invece di matrice intero, che non può essere segno di come il colore bitmap
  • il metodo imagesc prendere 4 parametri, che presenta i limiti con vettori x ed y
  • metodo imagesc inoltre sostiene scala (in realtà non so come funziona)


Qualcuno ha qualche suggerimento?

Aggiornamento: Ecco il risultato del metodo save in Armadillo. Non sembra immagine spettrogramma sopra. Mi manca qualcosa?

spec_t.save("spec_t.png", pgm_binary); 

enter image description here

Update 2: salvare spettrogramma con db e abs

mat spec_t_mag = db(abs(spec_t)); // where db method: m = 10 * log10(m); 
    mag_spec_t.save("mag_spec_t.png", pgm_binary); 

E il risultato:

enter image description here

+0

Per la matrice 'double', puoi fare come' imagesc' o molte altre funzioni grafiche di Matlab: Proietta il tuo intervallo di valori di matrice su una colormap fatta di numeri interi. Guarda la documentazione di Matlab su [indexed colors] (http://uk.mathworks.com/help/releases/R2015a/matlab/ref/graphics_i12.gif), nella documentazione di 'imagesc'. È un semplice esercizio di ridimensionamento. – Hoki

risposta

4

Armadillo è un pacchetto di algebra lineare, AFAIK non fornisce routine grafiche. Se usi qualcosa come opencv per quelli, allora è davvero semplice.

Vedere this link su opencv's imshow() e this link su come utilizzarlo in un programma.

Nota che opencv (come la maggior parte delle altre librerie) utilizza l'indicizzazione di riga maggiore (x, y) e Armadillo utilizza l'indicizzazione di colonna maggiore (riga, colonna), come spiegato here.

Per il ridimensionamento, è più sicuro convertire da solo i caratteri non firmati. In Armadillo che sarebbe qualcosa di simile:

`arma::Mat<unsigned char> mat2=255*(mat-mat.min())/(mat.max()-mat.min());` 

I t e f variabili sono per l'impostazione degli assi, non fanno parte della bitmap.

Per la semplice scrittura di un'immagine è possibile utilizzare Armadillo. Here è una descrizione su come scrivere le mappe della mappa grigia portatile (PGM) e della mappa dei pixel portatile (PPM). L'esportazione PGM è possibile solo per le matrici 2D, l'esportazione PPM solo per le matrici 3D, dove la 3a dimensione (dimensione 3) sono i canali per rosso, verde e blu.

Il motivo per cui la figura MATLAB sembra più bella è perché ha una mappa dei colori: una mappatura di ogni valore da 0..255 a un vettore [R, G, B] che specifica l'intensità relativa di rosso, verde e blu. Una foto ha un valore RGB in ogni punto:

colormap(gray); 
x=imread('onion.png'); 
imagesc(x); 
size(x) 

Questa è la terza dimensione dell'immagine.

La tua matrice è un'immagine 2D, quindi il modo più naturale per visualizzarlo è come i livelli di grigio (come è successo per il tuo spettro).

x=mean(x,3); 
imagesc(x); 

Ciò significa che le intensità R, G e B aumentano congiuntamente con i valori in mat. Puoi inserire una mappa dei colori di diverse combinazioni R, G, B in una variabile e usarla invece, ovvero y=colormap('hot');colormap(y);. La variabile mostra le combinazioni R, G, B per i valori di immagine (riscalati).

E 'anche possibile fare la tua mappa a colori (in MATLAB è possibile specificare 64 combinazioni R, G e B con valori compresi tra 0 e 1):

z[63:-1:0; 1:2:63 63:-2:0; 0:63]'/63 
colormap(z); 

Ora per aumentare i valori di immagine, intensità rosse diminuzione (a partire dal livello massimo), le intensità verdi aumentano rapidamente, diminuiscono e i valori blu aumentano dal minimo al massimo.

Poiché PPM viene visualizzato (non conosco il formato) per non supportare le mappe dei colori, è necessario specificare i valori R, G, B in una matrice 3D. Per un ordine di colore simile a quello che ci si z neet di fare un Cube<unsigned char> c(ysize, xsize, 3) e poi per ogni pixel y, x in mat2, fare:

c(y,x,0) = 255-mat2(y,x); 
c(y,x,1) = 255-abs(255-2*mat2(y,x)); 
x(y,x,2) = mat2(y,x) 

o qualcosa di molto simile.

+0

Grazie, ma voglio salvare bitmap in file png anziché mostrare in finestra. Opencv lo supporta? – R4j

+0

Ah, hai detto che volevi fare lo stesso di imagesc che sta visualizzando una matrice come bitmap. il salvataggio del contenuto di una finestra di figura è la funzionalità della GUI. Vedi il link nella modifica su come scrivere le immagini P {GP} M in Armadillo. –

+0

Aggiorno la mia domanda con il risultato 'save'. Ma lo spettrogramma non assomiglia a quello che mi aspetto come 'imagesc' su MATLAB. Mi manca qualcosa? I miei dati dei risultati sono complessi (perché lo faccio io). – R4j

2

È possibile utilizzare SigPack, una libreria di elaborazione del segnale su Armadillo. Ha il supporto dello spettrogramma e puoi salvare la trama in molti formati diversi (png, ps, eps, tex, pdf, svg, emf, gif). SigPack utilizza Gnuplot per la stampa.

Problemi correlati