【发布时间】:2014-10-03 18:06:58
【问题描述】:
我想使用 ARM Neon 将 8 位灰度图像的大小从 1280x960 调整为 4 倍至 320x240。
例如,我已经将 2 倍的大小从 640x480 调整为 320x240:
void divideimageby2(uint8_t * src, uint8_t * dest) {
//src is 640 x 480
//dst is 320 x 240
int h;
for (h = 0; h < 240; h++)
resizeline2(src + 640 * (h * 2 + 0), src + 640 * (h * 2 + 1), dt + 320 * h);
}
void resizeline2(uint8_t * __restrict src1, uint8_t * __restrict src2, uint8_t * __restrict dest) {
int w;
for (w = 0; w < 640; w += 16) {
uint16x8_t a = vpaddlq_u8(vld1q_u8(src1));
uint16x8_t b = vpaddlq_u8(vld1q_u8(src2));
uint16x8_t ab = vaddq_u16(a, b);
vst1_u8(dest, vshrn_n_u16(ab, 2));
src1 += 16;
src2 += 16;
dest += 8;
}
}
如果我想做类似的事情,我可以在 resizeline4 中使用什么样的 Neon 指令来聚合 4 行?
void divideimageby4(uint8_t * src, uint8_t * dest) {
//src is 1280 x 960
//dst is 320 x 240
int h;
for (h = 0; h < 240; h++)
resize_line2(src + 640 * (h * 4 + 0), src + 640 * (h * 4 + 1), src + 640 * (h * 4 + 2), src + 640 * (h * 4 + 3), dt + 320 * h);
}
void resizeline4(uint8_t * __restrict src1, uint8_t * __restrict src2, uint8_t * __restrict src3, uint8_t * __restrict src4, uint8_t * __restrict dest) {
int w;
for (w = 0; w < 1280; w += 16) {
//What to put here?
src1 += 16;
src2 += 16;
src3 += 16;
src4 += 16;
dest += 4;
}
}
【问题讨论】:
-
你想怎么做?你正在减少信息。见:What is the best image reduction algorithm;真正的答案是没有,因为reducing information 时有各种标准。你可以把它们结合起来。例如,第一次通过整数平均值,然后是第二次通过双三次将提供几乎与完整双三次一样好的质量,但会快得多。
-
这里的关键目标是速度。我希望它几乎和 Neon memcpy 一样快。
-
然后只消屏幕,这很快 :) 在花时间手动调整 NEON 之前,您至少应该评估不同的缩放算法。我的观点是,通过使用两个滤镜,您可以获得接近同等速度的很多更好的图像质量。跳过像素/行会更快并提供类似的质量;您在主图像上受到带宽限制。 NEON 将使 CPU 时间不占优势。无论如何,我祝你好运。
标签: image image-processing arm simd neon