我有一个尺寸为1024x1024
的PNG图片,其中包含RGB编码的高程数据。
我使用asarray
中的numpy
来读取图片:
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像素,从而减少数组大小。
非常感谢你的帮助!
答案 0 :(得分:4)
利用矢量化:
r = rgb_data[..., 0]
g = rgb_data[..., 1]
b = rgb_data[..., 2]
decoded_data = (256*r + g + b/256) - 32768
例如,rgb_data[..., 0]
一次选择所有 1024x1024
个红色值,256*r
将所有红色值一次性加倍,依此类推。由于代码中解释的for循环会带来很大的开销,因此避免它们会大大加快转换速度。
或者你可以使用单行:
decoded_data = (rgb_data[..., :3] * (256, 1, 1/256)).sum(axis=-1) - 32768
还有更多类似的精神方式。看看这篇文章中的评论,可以找到很好的单行集合。
答案 1 :(得分:3)
您可以使用非常强大的np.einsum
对流程进行矢量化。只需从系数中生成变换向量。
def decodeRGBArray(rgb_data):
transf = np.array([256., 1., 1./256., 0.])
return np.einsum('ijk,k->ij', rgb_data, transf) - 32768