x - это массив numpy.float32 со значениями от -200 до 0. Это значения дБ (децибел).

Когда я это сделаю (как рекомендовано здесь):

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

Я получаю оттенки серого или иногда почти черного изображения.

Как сопоставить число с плавающей точкой в [-200, 0] с 24-битным байтовым массивом RGB (с использованием карты цветов), который можно прочитать с помощью модуля PIL модуля Python с Image.fromarray(x, mode='RGB')?


Редактировать:

Требуемый аудио-файл .wav находится здесь , для которого мы хотим построить спектрограмма.

Вот код для тестирования:

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()

< EM> Примечания :

enter image description here

6
Basj 6 Янв 2017 в 15:58

3 ответа

Лучший ответ

Основываясь на ответе здесь, вы можете использовать matplotlib colormaps для преобразования массива numpy перед преобразованием в изображение.

#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()

Вы, вероятно, должны установить масштабирование соответствующим образом на основе ваших минимальных / максимальных значений.

Пример вывода:

Sample output

5
Community 23 Май 2017 в 11:45

Я не могу найти какие-либо подробности о mode = 'F' в документации, но я ожидаю, что он будет принимать значения пикселей в диапазоне от 0,0 до 1,0. Ваши значения полностью ниже этого диапазона, таким образом, черное изображение; вам нужно будет преобразовать их.

Для получения цветного изображения (вместо градаций серого) потребуется mode = 'P', что потребует от вас преобразования ваших данных в массив байтов.

1
jasonharper 6 Янв 2017 в 14:17

Для построения изображений с использованием цветовых карт я бы предложил вам использовать matplotlib. pyplot.imshow.

Результат этого с вашим test.wav файлом будет примерно таким:

enter image description here

Для получения более подробной информации о создании аудиограмм с использованием Python вы можете прочитать больше об этом здесь

3
BPL 17 Янв 2017 в 00:41