【问题标题】:How can I apply a Gaussian blur to a figure in `matplotlib`?如何将高斯模糊应用于“matplotlib”中的图形?
【发布时间】:2019-10-01 11:01:13
【问题描述】:

如何对matplotlib 中的图形应用高斯模糊?

更具体地说,我在matplotlib 图中绘制了以下图像:

使用以下代码生成:

import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import gaussian_filter


x = np.linspace(0, 3*np.pi, 100)
ys = []
for i in range(20):
    ys.append(np.sin(x) + (np.random.rand(100)-0.5)*np.random.rand())

new_y = ys[0]
new_x = x
for i in range(1, 20):
    new_x = np.concatenate([new_x, x])
    new_y = np.concatenate([new_y, ys[i]])

fig, ax = plt.subplots()
ax.hist2d(new_x, new_y, bins=50, cmap='inferno')
plt.show()

如何绘制此图像的高斯模糊版本?任何帮助将不胜感激。


我尝试过的:

我尝试在实际显示之前从图中抓取数据,将其转换为 numpy 数组,将高斯模糊应用于 numpy 数组,然后使用 plt.imshow 绘制模糊数组。

import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import gaussian_filter


x = np.linspace(0, 3*np.pi, 100)
ys = []
for i in range(20):
    ys.append(np.sin(x) + (np.random.rand(100)-0.5)*np.random.rand())

new_y = ys[0]
new_x = x
for i in range(1, 20):
    new_x = np.concatenate([new_x, x])
    new_y = np.concatenate([new_y, ys[i]])

fig, ax = plt.subplots()
ax.hist2d(new_x, new_y, bins=50, cmap='inferno')
fig.canvas.draw()

data = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='')
data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))
data2 = gaussian_filter(data, sigma=5)


plt.imshow(data2)

plt.pause(5)

但是,这显然对生成的图像没有任何影响。

【问题讨论】:

  • 不要调用ax.hist2d,而是使用np.hiostogram2d,如下所示,然后对其应用模糊处理。

标签: python numpy matplotlib image-processing scipy


【解决方案1】:

您可以使用pcolormesh 绘制直方图并使用shading="gouraud"。这可能不是真正的高斯,但我认为结果看起来像您正在搜索的,see the image here

代码:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 3*np.pi, 100)
ys = []
for i in range(20):
    ys.append(np.sin(x) + (np.random.rand(100)-0.5)*np.random.rand())

new_y = ys[0]
new_x = x
for i in range(1, 20):
    new_x = np.concatenate([new_x, x])
    new_y = np.concatenate([new_y, ys[i]])

fig, ax = plt.subplots()
data = np.histogram2d(new_x, new_y, bins=50)[0]
plt.pcolormesh(data.T, cmap='inferno', shading='gouraud')
fig.canvas.draw()

plt.pause(5)

【讨论】:

  • 这确实接近我想要的最终结果。但是,我没有看到一种方法来控制对图像应用多少模糊。
【解决方案2】:

我的猜测是,当您抓取渲染的直方图时,每个 bin 都有很多像素,因此平滑该图像几乎不会引起注意。增加平滑参数应该会改善您的结果。但它永远不会看起来像您期望的那样,因为每个输入 bin 都是一个像素块。

正确的解决方案是使用numpy.histogram2d 来生成直方图。然后,您可以适当地对其进行平滑处理并以任何您想要的方式显示它。

【讨论】:

    【解决方案3】:

    在 Markus 的回答的帮助下,我设法解决了这个问题。对np.histogram2d 返回的数据使用gaussian_filter 函数可以正确地将模糊应用于图像:

    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.ndimage import gaussian_filter
    
    x = np.linspace(0, 3*np.pi, 200)
    xs = []
    ys = []
    
    for i in range(200):
        xs.append(x+np.random.rand(200))
        ys.append(np.sin(xs[i]) + (np.random.rand(200)-0.5)*np.random.rand())
    
    new_y = ys[0]
    new_x = xs[0]
    for i in range(1, 200):
        new_x = np.concatenate([new_x, xs[i]])
        new_y = np.concatenate([new_y, ys[i]])
    
    fig, ax = plt.subplots()
    data = np.histogram2d(new_x, new_y, bins=150)[0]
    data = gaussian_filter(data, sigma=5)
    plt.pcolormesh(data.T, cmap='inferno', shading='gouraud')
    fig.canvas.draw()
    
    plt.pause(5)
    

    生成以下图像:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-05
      • 1970-01-01
      • 2020-08-02
      • 1970-01-01
      • 2016-09-23
      • 1970-01-01
      • 2018-01-19
      相关资源
      最近更新 更多