【问题标题】:Python, Numpy, OpenCV -- Creating a modified (and equally fast) "addWeighted" functionPython、Numpy、OpenCV——创建一个修改过的(同样快速的)“addWeighted”函数
【发布时间】:2017-07-17 13:51:02
【问题描述】:

我正在用 python 编写一个程序,该程序使用的函数与 openCV 中的 addWeighted 函数非常相似。不同之处在于它实际上并没有添加表示图像的 numpy 数组,而是采用在任何特定坐标处更亮的像素并使用该值。

然而,我发现,尽管这些函数做的事情非常相似,但addWeighted 函数要快得多。所以我的问题是,我怎样才能修改我当前的解决方案以同样快?有没有办法可以使用multiprocessing 模块或类似的东西?

代码如下:

image = np.zeros(image_1.shape)
for row_index, row in enumerate(image_1):
     for col_index, col in enumerate(row):
          pixel_1 = image_1[row_index, col_index]
          pixel_2 = image_2[row_index, col_index]
          sum_1 = int(pixel_1[0]) + int(pixel_1[1]) + int(pixel_1[2])
          sum_2 = int(pixel_2[0]) + int(pixel_2[1]) + int(pixel_2[2])

          if sum_2 > sum_1:
               image[row_index, col_index] = pixel_2
          else:
               image[row_index, col_index] = pixel_1

其中image_1image_2 都是表示图像的numpy 数组,两者具有相同的形状(720, 1280, 3)

【问题讨论】:

  • 故事的寓意:当你有 numpy 时不要循环像素,除非没有其他选择。几乎总是有一种更快的方法。与 C 之类的语言相比,Python 中的循环速度较慢。Numpy 是用 C 和 Fortran 构建的,因此它会在内部使用这些快速操作,而标准的 Python 循环会慢得多。

标签: python opencv numpy image-processing


【解决方案1】:

一种矢量化方法是 -

mask = image_2.astype(int).sum(-1) > image_1.astype(int).sum(-1)
out = np.where(mask[...,None], image_2, image_1)

步骤:

  • 转换为int dtypes,沿最后一个轴求和并执行逐元素比较。这会给我们一个面具。

  • 将此掩码与np.where 一起使用,扩展到相同的编号。暗淡作为输入数组进行选择。这采用了NumPy broadcasting 的概念以矢量化的方式进行选择。所以,这值得一看。

注意:或者,我们也可以使用keepdims=True 保留号码。求和时的暗淡,从而避免在下一步中扩展暗淡。

【讨论】:

  • 哇,我测试过了,效果很好!唯一的问题是,我不确定我是否完全理解代码。你用的是什么概念?有什么地方可以读到他们的资料吗?
  • 您的计算机非常擅长对多个数据点进行操作,例如 numpy 数组。这样做比遍历 numpy 数组中的每个数据点要高效得多。这基本上就是@Divakar 在这里所做的漂亮。
  • @user2457666 它使用broadcasting,我之前没有提到。添加链接。
  • 谢谢!我看着它,它开始在我的脑海中融合在一起。我的最后一个问题是[...,None] 部分有什么作用,为什么有必要?
  • @user2457666 这可能会有所帮助,特别是最后一部分 - stackoverflow.com/a/40383002
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-07
  • 1970-01-01
相关资源
最近更新 更多