2

我正在编写一小段 Renderscript 来动态拍摄图像并根据每个像素的 RGB 值将像素分类到“桶”中。桶的数量可能会有所不同,所以我的直觉是创建一个数组列表。显然,这在 Renderscript 中是不可能的,所以我想知道在脚本中创建动态结构列表的方法是什么。非常感谢任何帮助。

4

2 回答 2

1

我将尝试回答您对像素值进行分类的目标问题,而不是您创建动态大小的 structs 列表的标题问题


在不了解您的算法的情况下,我将使用以下两种算法之一来构建我的答案:

  1. RGB 联合直方图
    • 不使用相邻像素值。
  2. 连接组件

常见的建议。

两种算法都需要每个工作线程大量内存。此外,这两种算法都很难适应 GPU,因为它们需要某种随机内存访问(注)。因此,很可能这两种算法最终都将在 CPU 上执行。因此,减少“线程”的数量以避免成倍的内存需求是一个好主意。

注意:非合并(非顺序)内存访问 - 读取、写入或两者兼而有之。


RGB 联合直方图

最好的方法是使用 Renderscript 计算联合颜色直方图,然后在直方图上运行分类算法(可能在 CPU 上)。之后,您可以在 Renderscript 中执行像素级标签分配的最后一步。

整个过程与 Tim Murray 在 Google I/O 2013 上的 Renderscript 演示几乎完全相同。

联合颜色直方图必须具有硬编码大小。例如,32x32x32 RGB 联合直方图使用 32768 个直方图箱。这允许每个通道有 32 级色调。每个通道的误差为 256 个级别中的 +/- 2 个级别。


连接组件

我已经在 Renderscript 上成功实现了多线程连接组件标签。请注意,我的实现仅限于在 CPU 上执行;无法在 GPU 上执行我的实现。

先决条件。

  • 了解 Union-Find 算法(及其各种理论部分,例如路径压缩和排名)以及连接组件标记如何从中受益。

一些设计选择。

  1. 我使用一个与图像大小相同的 32 位整数数组来存储“链接”。
  2. 链接的发生方式与 Union-Find 相同,只是我没有排名的好处。这意味着树可能会变得高度不平衡,因此路径长度可能会变长。
  3. 另一方面,我在算法的各个步骤中执行路径压缩,通过缩短路径(深度)来抵消次优树合并的风险。

一个小而重要的实现细节。

  1. 存储在整数数组中的值本质上是“(x,y)”坐标到(i)本身的编码,如果像素是它自己的根,或者(ii)与当前具有相同标签的不同像素像素。

脚步。

  • 多线程阶段。
    • 将图像分成小块。
    • 在每个瓦片内,使用该瓦片本地的标签值计算连接的组件。
    • 在每个图块内执行路径压缩。
    • 将标签值转换为全局坐标并将图块的标签复制到主结果矩阵中。
  • 单线程阶段。
    • 水平缝合。
    • 垂直缝合。
    • 一轮全局路径压缩。
于 2014-06-15T21:05:50.697 回答
1

对此没有明确的答案。问题是动态内存管理对于像 RenderScript 这样的平台来说是一种厌恶——它很慢,暗示了很多关于页表和 TLB 的事情,在任意时间从给定的处理器上可能不容易保证,而且几乎从来都不是一个高效的做你想做的事的方法。

正确的选择完全取决于您在创建存储桶后对其进行的处理。您是否需要将所有内容分类而不将所有内容分类?只需创建一个每像素蒙版(或使用 Alpha 通道)并将类别与像素数据一起存储。你对每个桶的大小有上限吗?将每个存储桶分配为该大小。

抱歉,这是开放式的,但内存管理是让高性能代码戛然而止的事情之一。变通方法是必要的,但正确的变通方法因情况而异。

于 2013-09-30T17:44:44.363 回答