首页 > 解决方案 > 进行每像素计算的最快方法

问题描述

我一直在合并 2 个列表:

来自图像的RGB 列表和来自图像(y * w) 的像素列表。

rgb_list, pixel_list

我通过使用 zip 来做到这一点:

rgb_pixel = [zip(rgb, _pixels)]

这会给我:

rgb_pixel = [[(255, 0, 255), (0, 1)], [(0, 0, 0), (0, 2)]]

我这样做的原因是为了消除列表

RGB == 0, 0, 0 

同时获得正确的 x,y 坐标。

这是我用来删除上述坐标的代码:

non_blank_pixels = [i[1] for i in pixels if i[0] != (0, 0, 0)]

这将产生一个列表,只有 x、y 坐标是“非空白”RGB 不为 0、0、0

结果:

non_blank_pixels = [(0, 2), (0, 3)..]

完整代码:

rgb_list= tuple(zip(sct_img.raw[2::4], sct_img.raw[1::4], sct_img.raw[0::4]))
pixel_list= tuple((x, y) for y in range(height) for x in range(width))
rgb_pixel= tuple(zip(rgb, _pixels))
non_blank_pixels = [i[1] for i in pixels if i[0] != (0, 0, 0)]

这可行,但在2-5 毫秒的计算中,大部分都与这部分有关:

pixel_list = tuple((x, y) for y in range(height) for x in range(width))

有没有办法可以加快速度?

标签: python

解决方案


如果主要目标是有一个非空坐标列表,那么您只需要循环一次您的高度 * 宽度像素。

首先让我们弄清楚如何从 sct_img.raw 列表中获取给定像素的 RGB 值。我在这里做一些假设,因为我不熟悉你如何解析你的图像。您需要的数学可能略有不同,但如果我的假设不正确,该方法应该保持相关性。

我的假设是:

  • sct_img.raw 是一个由(3高)元素组成的数组,其中每个三元组元素代表下一个像素的 RGB 值。
  • 第一个三元组描述像素 (0,0)。下一个三元组像素 (0,1) 或换句话说第一行第二列等。
  • 这个数组首先存储 R 值,然后是 G,然后是 B,然后是下一个像素的 R,等等。

这意味着每 3 * width 条目描述一行像素。这意味着每当我们移动到下一行时,我们应该在数组中移动 3 * 宽度的元素。换句话说:第 0 行被 index0 to (3 * width) - 1中的所有元素捕获,第 1 行被 index 中的所有元素捕获,3 * width to (6 * width) - 1等等。

根据我们的假设,我们知道(sct_img.raw[0],sct_img.raw[1], sct_img.raw[2])描述像素 (0,0),而接下来的 3,(sct_img.raw[3],sct_img.raw[4], sct_img.raw[5])即将描述像素 (0,1)。当我们移动到下一列时,我们向下移动 3。

所以我们可以制定一个通用公式。位置 (x, y) 处任意像素的 R 值将是r_value = sct_image.raw[(x*3) + (y*3*width)]

最后,我们现在可以通过在添加像素之前检查像素是否为空来访问您的像素列表。

pixel_list = []
for x in range(width):
  for y in range(height):
    rgb = (sct_image.raw[(x*3) + (y*3*width)], sct_image.raw[(x*3) + (y*3*width) + 1], sct_image.raw[(x*3) + (y*3*width) + 2])
    pixel_list.append((x, y)) if rgb != (0, 0, 0)

# or as a one liner
pixel_list[(x, y) for x in range(width) for y in range(height) if (sct_image.raw[(x*3) + (y*3*width)], sct_image.raw[(x*3) + (y*3*width) + 1], sct_image.raw[(x*3) + (y*3*width) + 2]) != (0, 0, 0)]


推荐阅读