【问题标题】:Fast way to decode RGB image in python在python中解码RGB图像的快速方法
【发布时间】:2017-07-02 20:07:45
【问题描述】:

我有一个尺寸为1024x1024 的PNG 图像,其中包含RGB 编码的高程数据。 我使用来自numpyasarray 读取图像:

rgb_data = np.asarray(image)

这会产生一个尺寸为 (1024, 1024, 4) 的 3D 数组。 (我使用的是 RGBA)

我需要对该数据运行一些过滤器(高斯、中值),但我需要对解码的高程数据运行它。

高程数据可以用以下函数解码:

def decodeRGB(pixel):
    return (pixel[0] * 256 + pixel[1] + pixel[2] / 256) - 32768

解码后,我将得到一个维度为(1024, 1024) 的二维数组,其中包含解码后的高程数据。 (实际海拔高度)

到目前为止,我所拥有的是:

rgb_data = np.asarray(image)
decoded_data = np.zeros(tile.size)

for rownum in range(width):
    for colnum in range(height):
        decoded_data[rownum][colnum] = decodeRGB(rgb_data[rownum][colnum])

不幸的是,这个解决方案很慢。大约需要。 1024 x 1024 图像需要 10 秒。

有没有更高效的方法来实现这一点?

我的主要问题是数组的尺寸发生了变化。 我将从(1024, 1024, 4) 数组转到(1024, 1024) 数组。

我基本上是在寻找一种快速/有效的方法来将函数应用于图像中的每个 RGB 像素,从而减少数组大小。

非常感谢您的帮助!

【问题讨论】:

  • Python 不是读取、计算图像像素数据的好选择。获取LOW_LEVEL 语言!
  • @dsgdfg 当然,纯 Python 并不以速度着称,但这就是 Numpy 受欢迎的原因:它可以使用编译后的代码对机器原生数据的多维数组进行操作,因此会发生算术和循环在编译速度下,不是在 Python 字节码的相当缓慢的速度下在虚拟机上操作 Python 对象。
  • 64 Bit machine ram address + Virtual ram address + Main Thread ram address + Sub thread ram address 也许在@Sandro 项目上工作,但不是一直在工作。将内存地址保存到内存中,为什么更多制造商生产PCI card calculator module

标签: python arrays performance numpy image-processing


【解决方案1】:

利用矢量化:

r = rgb_data[..., 0]
g = rgb_data[..., 1]
b = rgb_data[..., 2]
decoded_data = (256*r + g + b/256) - 32768

例如,rgb_data[..., 0] 一次选择 all 1024x1024 红色值,256*r 一次将所有这些值乘以 256,等等。由于代码中解释的 for 循环会带来很大的开销,因此避免它们应该会大大加快转换速度。

或者您可以使用单线:

decoded_data = (rgb_data[..., :3] * (256, 1, 1/256)).sum(axis=-1) - 32768

在精神上还有更多相似的方式。查看这篇文章中的 cmets 以获得很好的单行代码集合。

【讨论】:

  • 甚至只是rgb_data @ [256, 1, 1/256, 0] - 32768
  • @Eric :-) 但是将所有这些零相乘和相加是一种浪费。不过,非常漂亮!
  • 然后使用rgb_data[..., :3] @ [256, 1, 1/256] - 32768。应该比构建整个事物然后求和使用更少的内存
  • @Eric 一件艺术品。介意我将其添加到帖子中吗?
  • @Eric @ 运算符是最近才添加的。对于 python 版本 rgb_data[..., :3].dot([256, 1, 1/256]) - 32768
【解决方案2】:

您可以使用非常强大的np.einsum 来矢量化该过程。只需从您的系数中制作一个变换向量即可。

def decodeRGBArray(rgb_data):
    transf = np.array([256., 1., 1./256., 0.])
    return np.einsum('ijk,k->ij', rgb_data, transf) - 32768

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-30
    • 1970-01-01
    相关资源
    最近更新 更多