python matplotlib 频谱图等获取图片像素点数据

python开发中,常使用绘图工具matplotlib绘制带有坐标轴或者colorbar的图像,比如下图是结合librosa进行频谱分析的梅尔频谱图。
当matplotlib绘制的图形只有部分是我们需要的,或者当我们没有条件将其生成的图像保存到本地,需要将像素数据放入内存中时,就会想到是否有一种办法可以将matplotlib绘制的图片部分/全部像素点提取出来,以备使用。
下面按照小编的思维方式介绍一下走弯路的过程,如果需要直接查看正确答案,移步至文章最后的代码,如有需要勘误之处,请移步评论区。
首先介绍业务需求,基于如下的代码,将频谱图中的频谱窗口(中间的绘图部分,不包括外侧色度条、空白区域和坐标轴)的像素点提取出来,且不能保存图像到本地进行二次读取操作(没有保存到本地的条件,需要到其他环境中运行,只能在内存中操作):

import matplotlib.pyplot as plt
import librosa
s = librosa.feature.melspectrogram(y=x, sr=fs)
fig, ax = plt.subplots()
s1 = librosa.power_to_db(s, ref=np.max)
img = librosa.display.specshow(s1, x_axis=xxx, y_axis='mel', sr=fs, ax=ax)
# 生成右侧的渐变色板条
fig.colorbar(img, ax=ax, format='%+2.0f dB')

保存到本地的图片如下:


频谱图.jpg

第一次尝试,想到了plt.subplots()或者librosa.display.specshow()返回的对象是否提供rgb三通道像素点的API?反复查看了几遍,发现有一个get_array(),获取代码如下:

img = librosa.display.specshow(S_dB, x_axis='time', y_axis='mel', sr=fs, ax=ax)
a = img.get_array()

a其实就是s1,并不是什么像素点了。
第二次尝试,想到是否可以定位到频谱区域的位置进行截图,丢弃坐标、色板条和空白部分。
考虑使用PIL的截图API,具体代码如下:

imageObject = Image.open(‘xxx’)
cropped = imageObject.crop((x1,y1,x2,y2))
cropped.save('xxx')

(x1,y1)和(x2,y2)分别是截图区域的左上角和右下角,但是发现,需要将图像存储到本地,不符合小编的要求。
需要注意的是,librosa 的所有绘图功能都依赖于 matplotlib,一般需要导入 matplotlib 的 pyplot API。
最后查阅资料发现,可以通过matplotlib.figure的canvas获取像素数据,具体地通过tostring_rgb()方法,查看tostring_rgb()方法的源码,发现仅有一行:

return np.asarray(self._renderer).take([0, 1, 2], axis=2).tobytes()

可以见得,是将self._renderer中的部分维度、部分位置的数据提取出来了,并不是直接解析某对象得到的。
由于目前还需要对像素数据进行截取,所以确定了[57:429,79:578:,]这个截取范围,至于确定范围的方法,需要根据图像调整,但是基本可以确定的是,在前面绘图参数和数据的尺寸不变的情况下,频谱图窗口的位置相对于整个图像是不变的,也就是说截取范围可以不变。
最后为了准确,使用PIL Image对象,将像素点填充进去,并show()出来,以查看截取的部分是否能够正常成像。

import matplotlib.pyplot as plt
from PIL import Image
import librosa
def test():
    # ---------原始频谱图------------------
    # 1、加载音频文件的时域信号、采样率到内存中
    # 2、根据时域信号、采样率等参数生成梅尔频谱
    s = librosa.feature.melspectrogram(y=x, sr=fs)
    # 3、matplotlib构建figure和一组子图,返回图形(matplotlib.figure)和坐标轴(matplotlib.axes.Axes)
    fig, ax = plt.subplots()
    # 4、频谱转成分贝单位的值
    S_dB = librosa.power_to_db(s, ref=np.max)
    # 5、显示频谱图像
    img = librosa.display.specshow(S_dB, x_axis='time', y_axis='mel', sr=fs, ax=ax)
    # ---------利用canvas对象获取像素点------------------
    # 6、绘制figure的边界框
    fig.canvas.draw()
    # 7、提取rgb数据,返回字节流对象
    buf = fig.canvas.tostring_rgb()
    # 8、获取canvas的宽度、高度
    ncols, nrows = fig.canvas.get_width_height()
    # 9、PIL创建图片对象,确定要截取的区域像素点的数量,这里是499×372
    im = Image.new("RGB",(499,372))
    # 10、将字节流转成numpy数组,并形状重置
    d = np.fromstring(buf, dtype=np.uint8).reshape(nrows, ncols, 3)
    # 11、截取目标区域的rgb像素点
    dd = d[57:429,79:578:,] 
    # ---------测试:查看像素点对应的图像------------------
    # 12、赋值给图片对象的像素点,每一个像素点都由rgb三通道组成
    for i in range(0,372):
        for j in range(0,499):
            im.putpixel((j,i),(int(dd[i][j][0]),int(dd[i][j][1]),int(dd[i][j][2])))
    # 13、查看截取的图像
    im.show()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容