4

我正在尝试将图像中的 r、g、b 通道绘制为 3-D 散点图。

当我有一个黑白图像时,这很有效,因为我得到一个散点图,在散点图的两端只有两个不同的簇。

然而,对于彩色图像,散点图在视觉上没有多大意义,因为在图像的颜色空间中存在对应于许多点的 r、g、b 值。

所以我最终得到如下图所示的东西 -

没有密度信息的 3-D 散点图

我想要实现的是以某种方式表示密度信息。例如,如果 (255,255,255) 对应的点数为 1000,而 (0,0,0) 对应的点数仅为 500,那么我希望 (255,255,255) 为深红色,而 (0,0,0) 为呈黄色/橙色

我如何在 matplotlib 中实现这一点?我对某种气泡效果也满意

4

1 回答 1

4

这是使用高斯 KDE 的尝试。它仍然远非完美,结果很大程度上取决于估计参数 ( bw_method)。也许有一种更简单的方法,也许是np.unique用来获取每种独特颜色的频率的方法。

这个想法是将颜色密度分布估计为多元高斯混合,并将其用作散点图的颜色图。

对于任何严重的事情来说它有点慢,但我认为它可以用足够小的图像给出很好的结果。也许一些基于 FFT+卷积的估计方法可能会更快。

让我们看一些代码。没什么特别的:它以喜欢的方式展平和重塑图像数据gaussian_kde,并返回 RGB 和密度分量。你可以玩一下bw_method,看看结果如何变化,越大,你得到的密度就越平滑。

from scipy.stats import gaussian_kde

def img_to_rgbk(img, bw=0.1):
    rgb = img.reshape(-1, 3).T
    k = gaussian_kde(rgb, bw_method=bw)(rgb)
    r, g, b = rgb

    return r, g, b, k

这是带有玩具图像的结果

img = chelsea()[100:200, 100:200]

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

r, g, b, k = img_to_rgbk(img, bw=0.5)
ax.scatter(r, g, b, c=k, alpha=0.2)

注意c=k用于将地图标记颜色设置为密度信息,alpha需要通过云看到一点。

切尔西

切尔西猫颜色密度

随机颜色

随机均匀的颜色密度

坡度

请注意,您可以在此处看到错误的带宽选择是如何产生误导的。足够小的bw_method每列应该基本上显示一种颜色,沿行重复。因此,每个点都应该具有相同的颜色(并且具有正确的带宽)。 光谱颜色图密度

渐变+噪点

这里有更好的带宽和一些噪音来传播颜色。请注意白色区域周围的较大密度,其中无噪声图中的不连续性变为密度最大值。 光谱 + 噪音 = 乐趣

于 2018-12-18T15:15:11.353 回答