在Python/Numpy中加速增量过滤器

2 投票
2 回答
906 浏览
提问于 2025-04-17 12:36

我正在写一个解压缩程序,其中一个功能是对RGB图像应用增量滤波。简单来说,就是读取那些只有第一个像素是绝对值(R1, G1, B1)的图像,后面的像素都是以(R[n]-R[n-1], G[n]-G[n-1], B[n]-B[n-1])的形式表示的,然后把它们转换成标准的RGB格式。

目前我使用numpy来处理,代码如下:

rgb = numpy.fromstring(data, 'uint8')
components = rgb.reshape(3, -1, order='F')
filtered = numpy.cumsum(components, dtype='uint8', axis=1)
frame = numpy.reshape(filtered, -1, order='F')

这里面:

  • 第一行创建了一个一维数组,表示原始图像;
  • 第二行把这个数组重新调整成

    [[R1, R2, ..., Rn], [G1, G2, ..., Gn], [B1, B2, ..., Bn]]
    
  • 第三行进行实际的去滤波处理

  • 第四行再把它转换回一维数组

问题是,这个过程对我来说太慢了。我分析了一下,发现大部分时间都花在了重新调整数组的形状上。

所以我在想:有没有办法避免重新调整形状,或者加快这个过程呢?

补充说明:

  • 我希望不需要为此写C语言扩展。
  • 我已经在使用多线程了。

2 个回答

2

我还不太明白为什么,你代码中的最后一步调整形状会复制数据。其实可以通过使用C语言的顺序来避免这种情况,而不是使用Fortran的顺序:

rgb = numpy.fromstring(data, 'uint8')
components = rgb.reshape(-1, 3)
filtered = numpy.cumsum(components, dtype='uint8', axis=0)
frame = filtered.reshape(-1)
1

首先,当你读取数据时,可以告诉它更多关于数据类型的信息,试试这个:

rgb = numpy.fromstring(data, '3uint8')

不需要重新调整形状。

接下来,对于一些大规模的操作,如果可以的话(而且 cumsum 就符合这个条件),可以使用 out= 参数,这样就不用移动数据了……所有操作都在原地进行。使用:

rgb.cumsum(axis=0,out=rgb)

如果你还是想把它变成一维的:

rgb = rgb.ravel()

撰写回答