我试图将图像中的r,g,b通道绘制为3-D散点图。
当我有黑白图像时,这很好用,因为我得到了一个散点图,在散点图的两端只有两个不同的簇。
但是对于彩色图像,散点图在视觉上没有多大意义,因为存在r,g,b值,它们对应于图像颜色空间中的许多点。
所以我最终得到了如下图所示的图像-
我想实现的是以某种方式表示密度信息。例如,如果对应于(255,255,255)的点数为1000,而对应于(0,0,0)的点数仅为500,则我想要(255,255,255)为深红色而(0,0,0)为黄色/橙色
如何在matplotlib中实现这一目标?我也可以使用某种气泡效果,其中(255,255,255)表示为比(0,0,0)大的气泡,尽管我感觉编码为颜色信息的密度信息在视觉上会更具吸引力
答案 0 :(得分: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
应该基本上每列显示一种颜色,并沿行重复。因此,每个点都应具有相同的颜色(并且具有正确的带宽)。
这里具有更好的带宽和一些噪音以散布颜色。请注意,白色区域周围的密度较大,在该区域中,无噪声图中的不连续点变为密度最大值。