【问题标题】:Image resizing using ARM NEON使用 ARM NEON 调整图像大小
【发布时间】:2013-06-16 21:03:34
【问题描述】:

我正在尝试实现此图像缩小算法的逐行版本:http://intel.ly/1avllXm,应用于 RGBA 8 位图像。

为了简化,考虑调整单行的大小,w_src -> w_dst。然后每个像素可以将其值贡献给权重为 1.0 的单个输出累加器,或者贡献给权重为 alpha 和 (1.0f - alpha) 的两个连续输出像素。在 C/伪代码中:

float acc[w_dst] = malloc(w_dst * 4);
x_dst = 0
for x = 0 .. w_src:
  if x is a pivot column:
     acc[x_dst] += (w_src[x] * alpha);
     x_dst++;
     acc[x_dst] += (w_src[x] * (1.0f - alpha);
  else
     acc[x_dst] += w_src[x];

最后,将每个累加器通道除以对其有贡献的源像素数(浮点值):

uint8_t dst = malloc(w_dst);
for x_dst = 0 .. w_dst
  dst[x_dst] = (uint8_t)round(acc[x_dst] / area);

我的参考纯 C 实现工作正常。但是,我想知道是否有一种方法可以使用 NEON 操作来加快速度(请记住,每个像素都是 8 位 RGBA)。谢谢!

【问题讨论】:

    标签: android performance algorithm image-processing neon


    【解决方案1】:

    很遗憾,NEON 不太适合这种工作。 如果是使用固定的源和目标分辨率调整图像大小,则可以使用动态向量进行 NEONize,但对可变数量的相邻像素求和并不是简单的 SIMDable。

    我建议用定点一替换浮点运算。仅此一项就会有很大帮助。

    此外,除法需要非常长的时间。它确实会损害性能,尤其是在循环内完成时。你应该用一个乘法代替它:

    uint8_t dst = malloc(w_dst);
    float area_ret = 1.0f/area;
    for x_dst = 0 .. w_dst
      dst[x_dst] = (uint8_t)round(acc[x_dst] * area_ret);
    

    【讨论】:

    • 是的,为了清楚起见,我已经简化了伪代码。我已经完成了所有明显的优化(乘法而不是除法,缓存浮点计算),仍然想知道是否有 SIMDable 方法。我将研究定点算法,尽管计算的准确性对该算法的结果有很大影响。
    • 很多人的常见误解之一是 fp 不如 float 准确。 Float 提供 24 位精度,这听起来可能已经足够了,但随着值的增加,它会截断最低有效位。另一方面,fp 的精度保持不变,直到最终转换为 int 才截断。在您的情况下,即使是 q14 fp 算法也会比当前的实现更准确。
    • ... aaaa 你是对的,当然。刚刚发现当前浮点实现中的错误,即当源行足够宽时精度会丢失,导致累加器值太大而无法获得精确的浮点精度。
    【解决方案2】:

    我的第二个想法是,垂直缩小非常适合 SIMDable,因为相同的算法可以应用于水平相邻的像素。

    所以这是我的建议:

    • 使用 q15 无符号 fp 算法通过 NEON 垂直调整大小。这 临时结果存储在 32 位/元素中。
    • 使用 ARM 使用 q15 无符号 fp 算法水平调整大小, 除以 area/typecast/pack 并将最终结果存储在 RGBA 中。

    请注意,按面积除应在q17中与 (1/area) 进行 LONG 乘法运算。

    为什么是 q17?如果执行 q15*q17,则结果在 q32 中,其中两个 32 位寄存器包含数据。而且您不需要执行任何“按位操作进行类型转换”,因为高位寄存器已经具有目标 8 位 int 值。这就是 fp 算术的美妙之处。

    也许我会在不久的将来编写完全优化的版本,完全在汇编中。

    【讨论】:

      猜你喜欢
      • 2013-07-22
      • 2014-10-03
      • 1970-01-01
      • 2015-05-02
      • 2011-09-07
      • 2021-06-25
      • 2012-02-28
      • 2013-08-21
      • 2012-08-09
      相关资源
      最近更新 更多