image - 使用 ARM NEON 将 8 位图像大小调整为 2

标签 image image-processing arm simd neon

我有一个 8 位 640x480 图像,我想将其缩小为 320x240 图像:

void reducebytwo(uint8_t *dst, uint8_t *src)
//src is 640x480, dst is 320x240

使用 ARM SIMD NEON 实现此目的的最佳方法是什么?有示例代码吗?

作为起点,我只想做相当于:

for (int h = 0; h < 240; h++)
    for (int w = 0; w < 320; w++)
        dst[h * 320 + w] = (src[640 * h * 2 + w * 2] + src[640 * h * 2 + w * 2 + 1] + src[640 * h * 2 + 640 + w * 2] + src[640 * h * 2 + 640 + w * 2 + 1]) / 4; 

最佳答案

这是您的代码与 Arm NEON 内在函数的一对一翻译:

#include <arm_neon.h>
#include <stdint.h>

static void resize_line (uint8_t * __restrict src1, uint8_t * __restrict src2, uint8_t * __restrict dest)
{
  int i;
  for (i=0; i<640; i+=16)
  {
    // load upper line and add neighbor pixels:
    uint16x8_t a = vpaddlq_u8 (vld1q_u8 (src1));

    // load lower line and add neighbor pixels:
    uint16x8_t b = vpaddlq_u8 (vld1q_u8 (src2));

    // sum of upper and lower line: 
    uint16x8_t c = vaddq_u16 (a,b);

    // divide by 4, convert to char and store:
    vst1_u8 (dest, vshrn_n_u16 (c, 2));

    // move pointers to next chunk of data
    src1+=16;
    src2+=16;
    dest+=8;
   }
}   

void resize_image (uint8_t * src, uint8_t * dest)
{
  int h;    
  for (h = 0; h < 240 - 1; h++)
  {
    resize_line (src+640*(h*2+0), 
                 src+640*(h*2+1), 
                 dest+320*h);
  }
}

它每次迭代处理 32 个源像素并生成 8 个输出像素。

我快速查看了汇编器输出,看起来没问题。如果您在汇编程序中编写 resize_line 函数、展开循环并消除管道停顿,则可以获得更好的性能。这将使您的性能提升估计为三倍。

尽管如此,它应该比您无需更改汇编程序的实现快得多。

注意:我还没有测试过代码...

关于image - 使用 ARM NEON 将 8 位图像大小调整为 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17815959/

相关文章:

javascript - 如何重构检查图像(用作 css 背景法师)是否存在以返回 bool 值的函数?

c - 在 gtk 窗口中流式传输 libuvc 代码的过程是什么?

html - 固定图像位置

python - OpenCV 车辆检测

java - 如何使用离散傅里叶变换在频域中的图像上实现低通滤波器?

android - 控制如何进入android linux内核中的DT_MACHINE_START for arm board

java - 如何在Java swing中调整面板中的图像?

android - 从图像中提取指纹

c - 链接需要链接两个相互依赖的静态库 : undefined reference

c++ - CMAKE - 调试/交叉构建?