Android 使用ARM NEON调整图像大小
我正在尝试实现此图像缩小算法的逐行版本:,应用于RGBA 8位图像Android 使用ARM NEON调整图像大小,android,performance,algorithm,image-processing,neon,Android,Performance,Algorithm,Image Processing,Neon,我正在尝试实现此图像缩小算法的逐行版本:,应用于RGBA 8位图像 为了简化,考虑调整单个行的大小,WSRC->WYDST。然后,每个像素可以将其值贡献给权重为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] +=
为了简化,考虑调整单个行的大小,WSRC->WYDST。然后,每个像素可以将其值贡献给权重为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];
最后,将每个累加器通道除以与其相关的源像素数(浮点值):
我的参考纯C实现工作正常。然而,我想知道是否有一种方法可以使用霓虹灯操作(记住,每个像素都是8位RGBA)来加快速度。谢谢 不幸的是,霓虹灯不太适合这种工作。 如果是使用固定的源和目标分辨率调整图像大小,则可以使用动态向量进行新化,但对可变数量的相邻像素求和并不简单 我建议用定点运算代替浮点运算。光是这一点就很有帮助 除此之外,分裂需要非常长的时间。它确实会损害性能,尤其是在循环内执行时。应将其替换为乘法,如:
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);
不幸的是,霓虹灯不太适合这种工作。 如果是使用固定的源和目标分辨率调整图像大小,则可以使用动态向量进行新化,但对可变数量的相邻像素求和并不简单 我建议用定点运算代替浮点运算。光是这一点就很有帮助 除此之外,分裂需要非常长的时间。它确实会损害性能,尤其是在循环内执行时。应将其替换为乘法,如:
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);
我的第二个想法是,垂直缩小非常容易模拟,因为相同的算法可以应用于水平相邻的像素 因此,以下是我的建议:
- 使用q15无符号fp算法使用NEON垂直调整大小。这个 临时结果存储在32位/元素中
- 使用q15无符号fp算法使用ARM水平调整大小, 按区域/类型转换/打包划分,并将最终结果存储在RGBA中
也许我会在不久的将来编写完全优化的版本,完全在汇编中。在我的第二个想法中,垂直缩小是非常容易模拟的,因为相同的算法可以应用于水平相邻的像素 因此,以下是我的建议:
- 使用q15无符号fp算法使用NEON垂直调整大小。这个 临时结果存储在32位/元素中
- 使用q15无符号fp算法使用ARM水平调整大小, 按区域/类型转换/打包划分,并将最终结果存储在RGBA中
也许我会在不久的将来编写这个完全优化的版本,完全在汇编中。是的,为了清晰起见,我简化了伪代码。我已经做了所有明显的优化(乘法而不是除法,缓存浮点计算),仍然想知道是否有一种可模拟的方法。我将研究定点算法,尽管计算的准确性对该算法的结果有很大影响。许多人的一个常见误解是fp的精度不如float。Float提供24位精度,这听起来足够了,但随着值的增加,它会截断最低有效位。另一方面,fp的精度保持不变,直到最终转换为整数时才会截断。在您的情况下,即使是q14 fp算法也比当前的实现更精确。。。。AAAA当然,你是对的。刚刚在当前的浮点实现中发现了一个错误,当源行足够宽时,精度会丢失,这使得累加器值对于精确的浮点精度来说太大。是的,为了清晰起见,我简化了伪代码。我已经做了所有明显的优化(乘法而不是除法,缓存浮点计算),仍然想知道是否有一种可模拟的方法。我将研究定点算法,尽管计算的准确性对该算法的结果有很大影响。许多人的一个常见误解是fp的精度不如float。Float提供24位精度,这听起来足够了,但随着值的增加,它会截断最低有效位。另一方面,fp的精度保持不变,直到最终转换为整数时才会截断。在您的情况下,即使是q14 fp算法也比当前的实现更精确。。。。AAAA当然,你是对的。刚刚在当前的浮点实现中发现了一个错误,当源行足够宽时,精度会丢失,这使得累加器值对于精确的浮点精度来说太大。