Mapping a float array to a 24-bit RGB image (e.g. using PIL)

x is an array of numpy.float32 with values ​​from -200 to 0 . This is dB (decibel).

When I do this (as recommended here ):

 Image.fromarray(x, mode='F') 

I get a grayscale image or sometimes an almost black image.

How to match the float in [-200, 0] with a 24-bit RGB byte array (using the color scheme) that can be read using the PIL PIL module with Image.fromarray(x, mode='RGB') ?


Edit:

The required .wav sound file is here for which we want to build a spectrogram .

Here is the code to check:

 import scipy, numpy as np import scipy.io.wavfile as wavfile import numpy as np from PIL import Image def stft(x, fftsize=1024, overlap=4): hop = fftsize / overlap w = scipy.hanning(fftsize+1)[:-1] return np.array([np.fft.rfft(w*x[i:i+fftsize]) for i in range(0, len(x)-fftsize, hop)]) def dB(ratio): return 20 * np.log10(ratio+1e-10) def magnitudedB(frame, fftsize=1024): w = scipy.hanning(fftsize+1)[:-1] ref = np.sum(w) / 2 return dB(np.abs(frame) / ref) sr, x = wavfile.read('test.wav') x = np.float32(x) / 2**15 s = magnitudedB(stft(x)).astype(np.float32).transpose()[::-1,] print "Max %.1f dB, Min %.1f dB" % (np.max(s), np.min(s)) im = Image.fromarray(s+200, mode='F') im.show() 

Notes:

  • Gray color palette, how to get another color code? for example this

  • My only requirement is that the output image can be read into a Tkinter frame / canvas (it works well with PIL im = Image.fromarray(...) , then ImageTk.PhotoImage(image=im) ) or wxPython frame / canvas .

enter image description here

+5
source share
3 answers

Based on the answer here, you can use matplotlib colormaps to convert a numpy array before converting to an image.

 #im = Image.fromarray(s+200, mode='F') from matplotlib import cm s = (s + 200)/200.0 # input data should range from 0-1 im = Image.fromarray(cm.jet(s, bytes=True)) im.show() 

You should probably set the scaling appropriately based on your min / max values.

Output Example:

Output example

+5
source

To display images using color palettes, I suggest you use matplotlib.pyplot.imshow .

The result of this with your test.wav file will be something like this:

enter image description here

For more information on creating sound spectrograms using python, you can read about it here.

+3
source

I cannot find any details about mode = 'F' in the documentation, but I would expect it to accept pixel values ​​in a range such as 0.0 - 1.0. Your values ​​are completely below this range, thus a black image; you will need to convert them.

Getting a color-coded image (instead of shades of gray) will require mode = 'P', for which you will need to convert your data into an array of bytes.

+1
source

Source: https://habr.com/ru/post/1262423/


All Articles