2017-01-06 17 views
5

x là một mảng numpy.float32, với các giá trị từ -200 đến 0. Đây là các giá trị dB (decibel).Hiển thị mảng nổi cho hình ảnh RGB 24 bit (sử dụng PIL chẳng hạn)

Khi tôi làm (theo khuyến cáo here):

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

tôi nhận được một tông màu xám hoặc hình ảnh đôi khi gần như màu đen.

Cách ánh xạ phao trong [-200, 0] tới mảng byte 24 bit (sử dụng bản đồ màu) có thể đọc được với mô-đun Python PIL với Image.fromarray(x, mode='RGB')?


Edit:

Các yêu cầu tập tin âm thanh .wav là here, mà chúng muốn âm mưu spectrogram.

Dưới đây là một số mã để kiểm tra:

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

Ghi chú:

  • Các bản đồ màu là xám, làm thế nào để có được bản đồ màu khác? như this one

  • Yêu cầu duy nhất của tôi là hình ảnh đầu ra có thể được đọc vào một khung Tkinter/canvas (nó hoạt động tốt với PIL của im = Image.fromarray(...) sau đó ImageTk.PhotoImage(image=im)) hoặc wxPython khung hình/canvas.

enter image description here

+0

Có lý do bất kỳ lý do tại sao bạn không sử dụng 'matplotlib.pyplot.imshow (X)'? –

+0

@Basj Bạn có bất kỳ dữ liệu nào để chơi cùng? Tôi muốn cung cấp cho nó một shot – BPL

+0

@NikolasRieble Tôi đã thêm một số mã trong câu hỏi, và một số lưu ý về lý do tại sao nên là đầu ra mong muốn: hình ảnh đầu ra nên được đọc vào khung/khung Tkinter hoặc khung wxPython/canvas. – Basj

Trả lời

5

Dựa theo câu trả lời here, bạn có thể sử dụng matplotlib colormaps để chuyển mảng numpy trước khi chuyển đổi thành hình ảnh.

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

Có lẽ bạn nên đặt tỷ lệ phù hợp dựa trên giá trị tối thiểu/tối đa của mình. sản lượng

mẫu:

Sample output

1

tôi không thể tìm thấy bất kỳ chi tiết về chế độ = 'F' trong tài liệu, nhưng tôi mong chờ nó lấy giá trị pixel trong một phạm vi như 0,0-1,0. Giá trị của bạn hoàn toàn nằm dưới phạm vi đó, do đó hình ảnh màu đen; bạn sẽ cần phải biến đổi chúng.

Bắt hình ảnh có màu xám (thay vì thang độ xám) sẽ yêu cầu chế độ = 'P', điều này sẽ yêu cầu bạn chuyển dữ liệu của mình thành một mảng byte.

+0

Tôi nghĩ về việc sử dụng 'mode = 'P'' nhưng sau đó sẽ có 256 màu tối đa mà không phải là tốt đẹp (8 bit) ... Có lẽ tôi phải sử dụng' chế độ =' RGB'' và làm một biến đổi [-200 , 0] => 24 bit int có thể đọc bằng chế độ RGB. Nhưng làm thế nào để làm điều đó ... – Basj

+0

Tôi thấy 'chế độ = 'F'': [chế độ] (http://pillow.readthedocs.io/en/3.1.x/handbook/concepts.html#concept-modes) trong tài liệu. Tôi đang nhìn vào các tài liệu sai? – fedepad

+0

Các tài liệu đó chỉ đơn giản nói rằng chế độ 'F' sử dụng phao; nó không nói gì về những gì những người nổi * có nghĩa là *, và tôi có một thời gian khó tưởng tượng ra một ý nghĩa hữu ích được gán cho các số âm. Bạn đang sử dụng numpy; bạn có thể làm những việc nhỏ nhặt như thêm 200 rồi chia cho 200, để lấy các giá trị vào một phạm vi khác có thể hoạt động. – jasonharper

3

Để vẽ hình ảnh bằng colormaps, tôi khuyên bạn nên sử dụng matplotlib.pyplot.imshow.

Kết quả của việc làm như vậy với tập tin test.wav của bạn sẽ là một cái gì đó như thế này:

enter image description here

Để biết thông tin chi tiết hơn về việc tạo spectrograms âm thanh sử dụng python bạn có thể đọc thêm về nó here

+0

Cảm ơn @BPL nhưng tôi đã biết cách tạo các spectrograms bằng Python và cách hiển thị chúng bằng matplotlib. Yêu cầu trong câu hỏi này là có đầu ra hình ảnh (sử dụng PIL hoặc nhẹ nhàng khác) * có thể được tải trong giao diện người dùng Tkinter hoặc wxPython * (sử dụng tiện ích canvas chẳng hạn). Tôi đang mã hóa một trình soạn thảo âm thanh, và điều này cần một giao diện người dùng thực hiện trong tkinter hoặc wxPython, như ở đây: http://stackoverflow.com/a/41504376/1422096. Bạn có nghĩ rằng nó có thể sử dụng giải pháp của bạn bên trong một giao diện người dùng tkinter như [ở đây] (http://stackoverflow.com/a/41504376/1422096)? – Basj

Các vấn đề liên quan