我想知道是否可以使用氖矢量将图像下采样3? 我正试图在纸上写一个算法,但似乎不可能。因为当您获得例如8个字节时,您无法获得3 * 3像素,因此没有足够的像素来完成下采样操作。根据2的缩减示例:Explaining ARM Neon Image Sampling 我想从一行加载16字节,然后加载8字节,然后将它们分配给32字节的向量,然后处理它的24字节的那个向量?
更新: 我根据答案写了一个示例代码,但是我在vst1_u8中遇到了分段错误......
inline void downsample3dOnePass( uint8_t* src, uint8_t *dst, int srcWidth)
{
// make sure rows/cols dividable by 8
int rows = ((srcWidth>>3)<<3);
// 8 pixels per row
rows=rows>>3;
for (int r = 0; r < rows; r++)
{
// load 24 pixels (grayscale)
uint8x8x3_t pixels = vld3_u8(src);
// first sum = d0 + d1
uint8x8_t firstSum = vadd_u8 ( pixels.val[0], pixels.val[1] );
// second sum = d1+d2;
uint8x8_t secondSum = vadd_u8 ( firstSum, pixels.val[2] );
// total sum = d0+d1+d2
uint8x8_t totalSum = vadd_u8(secondSum, firstSum);
// average = d0+d1+d2/8 ~9 for test
uint8x8_t totalAverage = vshr_n_u8(totalSum,3);
// store 8 bytes
vst1_u8(dst, totalAverage);
// move to next 3 rows
src+=24;
// move to next row
dst+=8;
}
}
答案 0 :(得分:2)
对于您处理的每个扫描线,您可以通过vld3.8
使用structure loads。如果你在r0..r2
中有第一,第二和第三行像素的起始地址,那么:
vld3.8 {d0,d1,d2}, [r0]
vld3.8 {d3,d4,d5}, [r1]
vld3.8 {d6,d7,d8}, [r2]
给你
d0
包含第一行的字节[0,3,6,9,12,15,18,21]
d1
包含第一行的字节[1,4,7,10,13,16,19,22]
d2
包含第一行的字节[2,5,8,11,14,17,20,23]
d3
.. d5
和第三行的d6
.. d8
相同然后将它们全部平均化。您可能希望扩展到16位,以免丢失精度。
编辑:总看起来有点像(离开九分):
//
// load 3x8 bytes from three consecutive scanlines
//
uint8x8x3_t pixels[3] =
{ vld3_u8(src), vld3_u8(src + srcwidth), vld3_u8(src + 2*srcwidth) };
//
// expand them to 16bit so that the addition doesn't overflow
//
uint16x8_t wpix[9] =
{ vmovl_u8(pixels[0].val[0]),
...
vmovl_u8(pixels[3].val[2]) };
//
// nine adds. Don't always add to wpix[0] because of possible dependencies.
//
wpix[0] = vaddq_u16(wpix[0], wpix[1]);
wpix[2] = vaddq_u16(wpix[2], wpix[3]);
wpix[4] = vaddq_u16(wpix[4], wpix[5]);
wpix[6] = vaddq_u16(wpix[6], wpix[7]);
wpix[0] = vaddq_u16(wpix[0], wpix[8]);
wpix[1] = vaddq_u16(wpix[2], wpix[4]);
wpix[3] = vaddq_u16(wpix[6], wpix[0]);
wpix[0] = vaddq_u16(wpix[1], wpix[3]);
[ .. divide-by-nine magic (in 16bit, aka for uint16x8_t), in wpix[0] ... ]
//
// truncate to 8bit and store back
//
vst1_u8(dst, vmovn_u16(wpix[0]);
祝你好运!