【问题标题】:Python OpenCV real time image stitching (n = 5) performance optimizationPython OpenCV实时图像拼接(n=5)性能优化
【发布时间】:2019-06-05 04:12:36
【问题描述】:

我需要即时拼接五个视频流。录制视频的摄像机并排安装在机架上,彼此之间的相对位置永远不会改变。因此,单应矩阵是静态的。

我正在遵循this github repo的方法:

从中间的图像开始,先向左缝合,然后将剩余的图像向右缝合。

该 repo 中的代码有效,但速度非常慢。我已经能够显着提高它的性能(300 倍),但仍然需要 0.25 秒来拼接一张包含五张图像的全景图(在 2015 年的 Macbook Pro 上)。

缓慢的部分:将cv2.warpPerspective(...) 的每个结果应用于拼接到该点的图像。我目前正在通过使用 alpha 通道并混合两个图像来做到这一点,灵感来自this SO answer正是这种混合使拼接速度变慢。

(伪)代码:

def blend_transparent(background, foreground):
    overlay_img = foreground[:, :, :3]  # Grab the BRG planes 
    overlay_mask = foreground[:, :, 3:]  # And the alpha plane

    # Again calculate the inverse mask
    background_mask = 255 - overlay_mask

    # Turn the masks into three channel, so we can use them as weights
    overlay_mask = cv2.cvtColor(overlay_mask, cv2.COLOR_GRAY2BGR)
    background_mask = cv2.cvtColor(background_mask, cv2.COLOR_GRAY2BGR)

    # Create a masked out background image, and masked out overlay
    # We convert the images to floating point in range 0.0 - 1.0
    background_part = (background * (1 / 255.0)) * (background_mask * (1 / 255.0))
    overlay_part = (overlay_img * (1 / 255.0)) * (overlay_mask * (1 / 255.0))

    # And finally just add them together, and rescale it back to an 8bit integer image
    return np.uint8(
        cv2.addWeighted(background_part, 255.0, overlay_part, 255.0, 0.0)
    )


for image in right_images:
    warped_image = cv2.warpPerspective(image, ...)
    mask = np.zeros(
        (warped_image.shape[0], warped_image.shape[1], 4), 
        dtype="uint8"
    )
    mask[0 : previously_stitched.shape[0], 0 : previously_stitched.shape[1]] = previously_stitched
    mask_rgb = mask[:, :, :3]  # Grab the BRG planes
    previously_stitched = blend_transparent(mask_rgb, warped_image)

所以我的问题是:有没有办法以更有效的方式将扭曲的图像应用于现有全景图?

我的完整工作代码在this repository

免责声明:我是一名网络开发人员,我对计算机视觉的了解非常有限。

【问题讨论】:

  • 我不清楚哪个部分需要时间。是调用 cv2.warpPerspective(...) 还是函数 blend_transparent ?在您的项目中,您使用的专利算法默认情况下不包含在 python 包中。这无助于测试您的问题。
  • 混合步骤是耗时的步骤。我更新了问题。关于专利:如果您在requirements.txt 固定的版本中安装python-opencv,则包含有问题的算法。

标签: python opencv image-stitching


【解决方案1】:

Alpha 通道在您的图像具有透明度时很有用,但在这里您需要通过转换手动添加 Alpha 通道。该通道可用于存储计算,但我认为您会失去性能。 我建议 blend_transparent 使用以下函数:

def blend_transparent(self, background, foreground):
    # Split out the transparency mask from the colour info
    overlay_img = foreground[:, :, :3]  # Grab the BRG planes

    res = background

    only_right = np.nonzero((np.sum(overlay_img, 2) != 0) * (np.sum(background,2) == 0))
    left_and_right = np.nonzero((np.sum(overlay_img, 2) != 0) * (np.sum(background,2) != 0))

    res[only_right] = overlay_img[only_right]
    res[left_and_right] = res[left_and_right]*0.5 + overlay_img[left_and_right]*0.5
    return res

如果当前没有设置值,您可以在结果中设置右图像像素的值。 如果已经设置了一个值,则计算左右值的平均值。 计算时间除以 1.6 倍。

由于您的投影已冻结,因此不需要每次都计算索引 only_right 和 left_and_right,我们可以计算一次并存储它们。这样做,您应该将计算时间除以 4。

【讨论】:

  • 这很聪明!缓存索引将计算时间缩短到 0.05 秒。
猜你喜欢
  • 1970-01-01
  • 2011-08-26
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
  • 2015-05-03
  • 1970-01-01
  • 2011-12-26
  • 1970-01-01
相关资源
最近更新 更多