2017-01-06 12 views
5

x - массив numpy.float32 со значениями от до 0. Это дБ (децибел).Оказание массива с поплавком для 24-разрядного изображения RGB (например, с использованием PIL)

Когда я делаю (в соответствии с рекомендациями here):

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

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

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


Edit:

Необходимый .wav аудиофайл here, для которого мы хотим построить spectrogram.

Вот код для проверки:

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

Примечания:

  • палитру является оттенки серого, как получить другую цветовую палитру? как this one

  • Мое единственное требование заключается в том, что выходное изображение может быть прочитан в Tkinter кадр/холст (он хорошо работает с PIL-х im = Image.fromarray(...) затем ImageTk.PhotoImage(image=im)) или WxPython кадр/холст.

enter image description here

+0

Есть ли причина, почему вы не используете 'matplotlib.pyplot.imshow (X)'? –

+0

@Basj У вас есть данные для игры? Я бы хотел сделать снимок – BPL

+0

@NikolasRieble. Я добавил код в вопрос, а также примечание о том, почему должен быть желаемый вывод: выходное изображение должно быть прочитано в кадр/холст Tkinter или кадр/холст wxPython. – Basj

ответ

5

Based в ответе here вы можете использовать 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() 

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

Пример:

Sample output

1

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

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

+0

Я думал об использовании 'mode = 'P'', но тогда будет максимум 256 цветов, что не очень приятно (8 бит) ... Может быть, мне нужно использовать' mode =' RGB'' и сделать преобразование [-200 , 0] => 24 бит int, которые могут быть прочитаны режимом RGB. Но как это сделать ... – Basj

+0

Я вижу 'mode = 'F'': [режимы] (http://pillow.readthedocs.io/en/3.1.x/handbook/concepts.html#concept-modes) в документации. Я смотрю на неправильные документы? – fedepad

+0

Эти документы просто говорят, что режим «F» использует поплавки; он ничего не говорит о том, что эти плавающие * означают *, и мне трудно представить, что полезный смысл присваивается отрицательным числам. Вы используете numpy; вы можете тривиально делать такие вещи, как добавление 200, затем делить на 200, чтобы получить значения в другом диапазоне, который может работать. – jasonharper

3

Чтобы сфотографировать изображения с помощью цветовых карт, я предлагаю вам использовать matplotlib.pyplot.imshow.

Результат делать это с файлом test.wav будет что-то вроде этого:

enter image description here

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

+0

Спасибо @BPL, но я уже знаю, как создавать спектрограммы с помощью Python и как отображать их с помощью matplotlib. Требование в этом вопросе состоит в том, чтобы иметь вывод изображения (с использованием PIL или anothing else) *, который может быть загружен в пользовательский интерфейс Tkinter или wxPython * (например, с помощью виджета холста). Я кодирую аудиоредактор, и для этого нужен пользовательский интерфейс, сделанный в tkinter или wxPython, например здесь: http://stackoverflow.com/a/41504376/1422096. Считаете ли вы возможным использовать свое решение внутри пользовательского интерфейса tkinter, например [здесь] (http://stackoverflow.com/a/41504376/1422096)? – Basj