PoseWarping:如何矢量化此 for 循环(z 缓冲区)

2024-03-21

我正在尝试使用地面真实深度图、姿势信息和相机矩阵将帧从视图 1 扭曲到视图 2。我已经能够删除大部分 for 循环并将其矢量化,除了一个 for 循环。扭曲时,由于遮挡,视图 1 中的多个像素可能会映射到视图 2 中的单个位置。在这种情况下,我需要选择深度值最低的像素(前景对象)。我无法对这部分代码进行矢量化。任何帮助向量化这个 for 循环的帮助都是值得赞赏的。

Context:

I'm trying to warp an image into a new view, given ground truth pose, depth, and camera matrix. After computing warped locations, I'm rounding them off. Any suggestions to implement inverse bilinear interpolation are also welcome. My images are of full HD resolution. Hence it is taking a lot of time to warp the frames to the new view. If I can vectorize, I'm planning to convert the code to TensorFlow or PyTorch and run it on a GPU. Any other suggestions to speed up warping, or existing implementations are also welcome.

Code:

def warp_frame_04(frame1: numpy.ndarray, depth: numpy.ndarray, intrinsic: numpy.ndarray, transformation1: numpy.ndarray,
                  transformation2: numpy.ndarray, convert_to_uint: bool = True, verbose_log: bool = True):
    """
    Vectorized Forward warping. Nearest Neighbor.
    Offset requirement of warp_frame_03() overcome.
    mask: 1 if pixel found, 0 if no pixel found
    Drawback: Nearest neighbor, collision resolving not vectorized
    """
    height, width, _ = frame1.shape
    assert depth.shape == (height, width)
    transformation = numpy.matmul(transformation2, numpy.linalg.inv(transformation1))

    y1d = numpy.array(range(height))
    x1d = numpy.array(range(width))
    x2d, y2d = numpy.meshgrid(x1d, y1d)
    ones_2d = numpy.ones(shape=(height, width))
    ones_4d = ones_2d[:, :, None, None]
    pos_vectors_homo = numpy.stack([x2d, y2d, ones_2d], axis=2)[:, :, :, None]

    intrinsic_inv = numpy.linalg.inv(intrinsic)
    intrinsic_4d = intrinsic[None, None]
    intrinsic_inv_4d = intrinsic_inv[None, None]
    depth_4d = depth[:, :, None, None]
    trans_4d = transformation[None, None]

    unnormalized_pos = numpy.matmul(intrinsic_inv_4d, pos_vectors_homo)
    world_points = depth_4d * unnormalized_pos
    world_points_homo = numpy.concatenate([world_points, ones_4d], axis=2)
    trans_world_homo = numpy.matmul(trans_4d, world_points_homo)
    trans_world = trans_world_homo[:, :, :3]
    trans_norm_points = numpy.matmul(intrinsic_4d, trans_world)
    trans_pos = trans_norm_points[:, :, :2, 0] / trans_norm_points[:, :, 2:3, 0]
    trans_pos_int = numpy.round(trans_pos).astype('int')

    # Solve occlusions
    a = trans_pos_int.reshape(-1, 2)
    d = depth.ravel()
    b = numpy.unique(a, axis=0, return_index=True, return_counts=True)
    collision_indices = b[1][b[2] >= 2]  # Unique indices which are involved in collision
    for c1 in tqdm(collision_indices, disable=not verbose_log):
        cl = a[c1].copy()  # Collision Location
        ci = numpy.where((a[:, 0] == cl[0]) & (a[:, 1] == cl[1]))[0]  # Colliding Indices: Indices colliding for cl
        cci = ci[numpy.argmin(d[ci])]  # Closest Collision Index: Index of the nearest point among ci
        a[ci] = [-1, -1]
        a[cci] = cl
    trans_pos_solved = a.reshape(height, width, 2)

    # Offset both axes by 1 and set any out of frame motion to edge. Then crop 1-pixel thick edge
    trans_pos_offset = trans_pos_solved + 1
    trans_pos_offset[:, :, 0] = numpy.clip(trans_pos_offset[:, :, 0], a_min=0, a_max=width + 1)
    trans_pos_offset[:, :, 1] = numpy.clip(trans_pos_offset[:, :, 1], a_min=0, a_max=height + 1)

    warped_image = numpy.ones(shape=(height + 2, width + 2, 3)) * numpy.nan
    warped_image[trans_pos_offset[:, :, 1], trans_pos_offset[:, :, 0]] = frame1
    cropped_warped_image = warped_image[1:-1, 1:-1]
    mask = numpy.isfinite(cropped_warped_image)
    cropped_warped_image[~mask] = 0
    if convert_to_uint:
        final_warped_image = cropped_warped_image.astype('uint8')
    else:
        final_warped_image = cropped_warped_image
    mask = mask[:, :, 0]
    return final_warped_image, mask
    
    

代码说明

  • 我使用方程 [1,2] 来获取 view2 中的像素位置
  • 一旦获得像素位置,我需要确定是否存在任何遮挡,如果有,我必须选择前景像素。
  • `b = numpy.unique(a, axis=0, return_index=True, return_counts=True)` 给了我独特的位置。
  • 如果 view1 中的多个像素映射到 view2 中的单个像素(碰撞),则“return_counts”将给出大于 1 的值。
  • `collision_indices = b[1][b[2] >= 2]` 给出涉及碰撞的索引。请注意,这只会为每次碰撞提供一个索引。
  • 对于每个这样的碰撞点, `ci = numpy.where((a[:, 0] == cl[0]) & (a[:, 1] == cl[1]))[0]` 提供索引view1 中映射到 view2 中同一点的所有像素。
  • `cci = ci[numpy.argmin(d[ci])]` 给出具有最低深度值的像素索引。
  • `a[ci] = [-1, -1]` 和 `a[cci] = cl` 将所有其他背景像素映射到框架外的位置 (-1,-1),因此将被忽略。

[1] https://i.stack.imgur.com/s1D9t.png https://i.stack.imgur.com/s1D9t.png
[2] https://dsp.stackexchange.com/q/69890/32876 https://dsp.stackexchange.com/q/69890/32876


如果您尝试在 99.9% 的情况下进行图像处理(您就是这样),您会遇到默认 Numpy 函数未涵盖的边缘情况。我不确定如何使用 Numpy 对该代码进行矢量化,但您不必这样做。看看赛通。它允许您创建自定义 C++ 扩展(这就是 Numpy 的真正含义)。您可以从基本 Python 代码开始,逐步添加键入信息以及禁用特定于 Python 的检查(例如禁用环绕和边界检查)。这些可能会导致崩溃,因此一次进行一项优化并确保测试每一步。如果您的代码是可并行的(对我来说似乎是这样)并且您对多线程感到满意,您可以释放 GIL (使用 nogil:) 并将原始数组、偏移量和计数传递给 Cython 函数进行操作在不同线程的共享内存上(使用内置线程池通常效果很好)。如果您想遵循此路径,请告诉我,以便我可以在此答案中添加更多详细信息和代码片段,或者您是否更愿意坚持使用 Numpy。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PoseWarping:如何矢量化此 for 循环(z 缓冲区) 的相关文章

随机推荐

  • 为过程或函数 cdc.fn_cdc_get_all_changes_ 提供的参数数量不足

    看似有效的代码 用于查询表中最新跟踪的更改Fields DECLARE Begin LSN BINARY 10 End LSN BINARY 10 SET Begin LSN sys fn cdc get min lsn Fields SE
  • Firefox 打开新选项卡而不是弹出窗口? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我发现在最新版本的 Firefox 中 添加了一个名为 在新选项卡中打开新窗口 的设置 当我保持打开状态时 所有弹出窗口 使用打开的jav
  • 将 Html.Partial 添加到 Javascript

    我想使用 ASP NET Html Partial 视图在 Javascript 中设置一个字符串 问题是 Html Partial 给出了 HtmlString 而不是我可以使用 JQuery 处理的 Javascript 字符串 Jav
  • 内嵌显示图像和文本

    我无法在标题的每一侧获取图像 我尝试过 display inline block 但这不适合我 这里是jsfiddle http jsfiddle net uyjmffbu inline image display inline block
  • 异常保证和按值传递

    我最近在多种情况下遇到过这个问题 其中表达的一些观点让我感到惊讶 这是第一个简单的例子 void f std vector
  • 在 Objective-C 中使用枚举?

    这是在 Objective C 中使用 emum 的正确方式 甚至是有效方式 吗 即不使用 menuItem 而只是定义了一个列表 add 1 load 2 list 3 等 enum menuItems add 1 save load l
  • AsyncTaskLoader:方向更改后未调用 onLoadFinished

    我有一个AsyncTaskLoader对于长时间运行的任务 当加载程序运行时 我的活动由于方向变化而被破坏 onLoadFinished回调未被调用 我可以以某种方式将加载程序 重新附加 到我的新活动 它的回调吗 这是我的 简化的 Acti
  • Django python 中的Search_fields

    我想知道如何使用外键来执行搜索 例如 class Product models Model name models CharField max length 127 description models TextField code mod
  • 将 mongodb 作为 Windows 服务运行

    我已经在 win32 上安装了 mongodb 我正在尝试将其作为服务运行 我已按照此处发布的说明进行操作 http www deltasdevelopers com post Running MongoDB as a Windows Se
  • SQL Server 2005 查询的性能

    这需要 4 秒来执行 有 2000 000 行 为什么 DECLARE AccountId INT DECLARE Max INT DECLARE MailingListId INT SET AccountId 6730 SET Max 2
  • 将选择器添加到 UIButton

    I have ViewController然后两个不同的ViewControllers扩展该主要ViewController 一个用于 iPhone 另一个用于 iPad iPad 的ViewController实例化一个单独的扩展UIVi
  • 哪些真实平台将硬件端口映射到内存地址?

    我有时会在某些平台上看到以下 C 或 C 代码的语句 int ptr ptr 0 可能会导致写入硬件输入输出端口 如果ptr恰好存储了该端口映射到的地址 通常它们被称为 嵌入式平台 此类平台的真实例子有哪些 根据我的经验 大多数系统都使用内
  • 使用自定义区域性时 ResourceManager 未选择正确的资源集

    我使用以下代码创建了一个本地化的 MVC 网站 亚历克斯 阿达米安 Alex Adamyan 的博客 http adamyan blogspot com 2010 07 addition to aspnet mvc localization
  • 如何在类Unix操作系统下方便的运行SBCL代码?

    David James 写了问题和答案 我将对其进行编辑以符合 Stackoverflow 标准 使用 SBCL 您可以将 Lisp 代码编译为机器代码 像 Java net C 甚至 C 一样 您将需要运行时 所以有两种方法来编译 Com
  • CATALINA_OPTS 在 Tomcat 中如何工作?

    我很好奇 CATALINA OPTS 在 Apache Tomcat 的后台如何工作 是的 我知道它在 Tomcat 启动和运行时执行 我添加了一些参数供我的程序使用 甚至我使用它很长时间 将其添加到我的 VM 参数中 但不确定它是如何运行
  • 有条件的承诺

    在我的脚本中 我需要检索一个字典以将编码值转换为名称 ajax retrieve dictionary done function dictionary convert encoded values into names done func
  • 计算时间戳之间的营业时间[重复]

    这个问题在这里已经有答案了 我使用的是Postgres 8 3 目前没有选择版本 我的原始数据表如下 ID start time finish time 01 2013 01 23 10 47 52 05 2013 02 25 11 18
  • 如何在 Scala 中创建没有文字元素名称的 XML 根节点?

    我正在寻找创建一个这样的文档
  • Spark ml 和 PMML 导出

    我知道可以将模型导出为PMML with Spark MLlib 但是关于Spark ML 是否可以转换LinearRegressionModel from org apache spark ml regression to a Linea
  • PoseWarping:如何矢量化此 for 循环(z 缓冲区)

    我正在尝试使用地面真实深度图 姿势信息和相机矩阵将帧从视图 1 扭曲到视图 2 我已经能够删除大部分 for 循环并将其矢量化 除了一个 for 循环 扭曲时 由于遮挡 视图 1 中的多个像素可能会映射到视图 2 中的单个位置 在这种情况下