我尝试了几种不同的方法来生成视频文件的DTFT的灰度PNG,但我的结果与其他人发布的内容不同。我没有使用matplotlib绘制到屏幕上(正如所有示例所做的那样),而是尝试使用scikit-image创建一个PNG(在其他项目中使用它之后我相信它。)
这是我的代码,需要一个mp4文件(这里我使用隐藏在DTFT中的Aphex Twin's song with the notorious Demon Face)。我特别感兴趣的是让它与the av library一起使用,我确信它正在正确地读取文件并生成一个浮点数的numpy数组。
import numpy as np
import av
import skimage.io
import scipy.signal as signal
container = av.open("tmp/aphex.mp4")
frames = container.streams.audio[0].frames
chunk = container.streams.audio[0].frame_size // 2 # bug in av?
rate = container.streams.audio[0].rate
fltp = np.zeros((frames, chunk), dtype=float)
for n, frame in enumerate(container.decode(audio=0)):
fltp[n, :] = np.frombuffer(frame.planes[0], dtype=float)
fltp = fltp.flatten()
# check that it worked by playing it (just one channel)
fltp.tofile("tmp/aphex.raw")
# play -t raw -r 44100 -e floating-point -b 32 -c 1 tmp/aphex.raw
custom_chunk = 4096
freqs, times, data = signal.spectrogram(fltp,
fs=rate,
nperseg=custom_chunk,
detrend="linear")
data = data - np.min(data)
data = data / np.max(data)
data = 1 - data
skimage.io.imsave("tmp/aphex.png", data)
但是这会产生一个非常稀疏的图像(这是一个图像,诚实,而不是一个大的垂直空间)如果我添加以下行
data = np.log10(data)
data[data == -np.inf] = 0
引入一个对数比例(尽可能多)然后它看起来更奇怪(由于2MB上传限制而被裁剪)
我已经尝试了很多其他的东西,比如尝试按列进行标准化(看起来稍微好些,但仍然很奇怪)但是我的频谱图看起来仍然没有像它们应该的那样。
有人知道我做错了吗?
(我也尝试直接在每个块上使用numpy.fft.rfft / scipy ......我的图像与这些图像看起来非常相似。我也尝试了几种不同的电影/歌曲)