【问题标题】:Efficient colorization of numpy matrix by value?按值对numpy矩阵进行有效着色?
【发布时间】:2012-12-25 16:15:03
【问题描述】:

我有一个看起来像这样的 numpy ndarray:

[[0, 0.25, 1,  ...., 0.5, 0.23 ],
 [0.3, 0.75, 1, ..., 0.5, 0.37 ],
  ...,
  ...,
 [0, 0.25, 1,  ...., 0.5, 0.23 ],
 [0.3, 0.75, 1, ..., 0.5, 0.37 ]]

基本上每个值都在 0 - 1.0 范围内

我想将其可视化为位图,目前我有一个非常慢的循环,基本上是这样做的:

for i, row in enumerate(data):
    for j, val in enumerate(row):
        yield val_to_rgb(val)

然后它将获取 RGB 组件的 3 元组并对其执行 PIL putdata 并创建一个 PNG。

我需要这样做很多次,这种ghetto方法很慢,而且着色很丑。

我的问题是这样的:

我可以应用一系列矩阵运算来生成包含原始 RGB 值的彩色矩阵吗?

这实际上由两个问题组成:

  1. 我可以应用什么最有效的转换来从上述矩阵中获取 RGB 元组
  2. 有没有一种“好”的方法可以将 (0, 1.0) 值转换为彩色表示?

编辑:澄清-我希望将其保存为 PNG,而不仅仅是实时查看。原因是其中很多都是在无头机器上执行的,然后我会在事后对其进行检查。

当前算法的输出看起来很糟糕:

【问题讨论】:

  • 了解您的 val_to_rgb 函数的作用真的很有帮助。

标签: python colors numpy


【解决方案1】:

matplotlib 具有 imshow 功能,您可以开箱即用。

您所做的通常是通过“矢量化”完成的。您定义一个函数并让 numpy 进行迭代:

vec = np.vectorize(val_to_rgb)
rgb_data = vec(data)

【讨论】:

  • np.vectorize 之类的只是语法糖:它们让你的代码看起来更漂亮,但循环仍然在 python 中运行,因此没有性能优势。
  • Matplotlib 似乎不适用于无头机器上的应用程序。我正在运行大量并行化,至少在 OSX 上,我遇到了与尝试从守护进程中使用核心映像功能相关的错误。看起来这个库更多地是为实时检查数据集而构建的。
  • @amirpc matplotlib 在无头机器上没问题...您只需要更改后端以使用纯非 gui 的。
  • @seberg - 确实如此。我已经让它与一个 svg 后端一起工作,它似乎运行得很好,谢谢你的提示!
  • OOTB 是否与开箱即用相同?
【解决方案2】:

我对 PIL 不是很熟悉,但我猜它会吞下一个形状为 (rows, cols, 3) 的 numpy 数组并将其变成图像。所以你想重写你的 val_to_rgb 函数,使它适用于数组,而不是标量,并将 RGB 值放在形状的最后一维中。

例如,假设您想将值解释为灰度,0 表示黑色,1 表示白色。您当前采用标量输入的函数如下所示:

def val_to_rgb(val) :
    return (int(val * 255),) * 3

矢量化的形式类似于:

def vals_to_rgbs(vals) :
    ret = np.zeros(vals.shape + (3,),  dtype='uint8')
    ret[...] = vals.reshape(vals.shape + (1,)) * 255
    return ret

>>> vals_to_rgb(np.random.rand(10,10)).shape
(10, 10, 3)
>>> vals_to_rgb(np.random.rand(10,10)).dtype
dtype('uint8')

重塑是让广播发挥其魔力的地方。

想法可能会变得更复杂,因此如果您需要帮助矢量化您的特定 val_to_rgb 函数,请发布您的代码,我很乐意试一试。

【讨论】:

  • 我不确定我是否完全理解您在这里所说的内容。看起来你的意思是我可以在每个单元格中添加一个额外的数据,这是一个 RGB 值的 3 分量列表,对吗?如果是这样,这样做的原因是什么?
  • @amirpc - 他的观点是,您可以使用您的颜色图(即单独的红色、绿色和蓝色波段)制作一个 MxNx3 数组,PIL 会将数组解释为彩色图像。如果您真的想要一个纯像素到像素的表示(即数组中的像素数与图像中的像素数完全相同),那么这样做会更快且更简单。另一方面,Matplotlib 具有更多功能,并且可以轻松使用多个颜色图,但是在显示空间中“认为”你必须跳过几圈才能保存为像素-到像素表示。
猜你喜欢
  • 2012-04-22
  • 2016-09-27
  • 1970-01-01
  • 1970-01-01
  • 2021-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
相关资源
最近更新 更多