如何在 SSE 中解交织图像通道

Posted

技术标签:

【中文标题】如何在 SSE 中解交织图像通道【英文标题】:how to deinterleave image channel in SSE 【发布时间】:2016-03-08 15:38:33 【问题描述】:

有什么方法可以对 32bpp 图像通道进行 DE-interleave,类似于下面的 neon 代码。

//Read all r,g,b,a pixels into 4 registers
uint8x8x4_t SrcPixels8x8x4= vld4_u8(inPixel32);

ChannelR1_32x4 = vmovl_u16(vget_low_u16(vmovl_u8(SrcPixels8x8x4.val[0]))), 
channelR2_32x4 = vmovl_u16(vget_high_u16(vmovl_u8(SrcPixels8x8x4.val[0]))), vGaussElement_32x4_high);

基本上我希望所有颜色通道在单独的向量中,每个向量都有 4 个 32 位元素来做一些计算,但我对 SSE 不是很熟悉,在 SSE 中找不到这样的指令,或者如果有人可以提供更好的方法来做那?非常感谢任何帮助

【问题讨论】:

您的像素是 4 x 8 位 RGBA,即每个像素 32 位吗?以及你想要什么输出格式,分离 8 位 R、G、B 和 A 的向量,还是你也想同时将 8 位值解包为 32 位? 是的,我的图像是每像素 32 bpp 8 位,是的,我还想同时将 8 位值解压缩为 32 位。类似于 R、R、R、R(其中每个 R 占用 32 位),类似地 B、B、B、B ......当我将每个 R、B、G、A 乘以某个 32 位值时,这基本上会有所帮助。 我只是想实现高斯模糊,其中我的高斯系数是 32 位,所以我需要这个去交织,然后我可以简单地将去交织向量与高斯向量相乘 您可能不想为这样的过滤器执行 32x32 位乘法,尤其是在它对性能至关重要的情况下。使用定点 16x16 乘法。 你能告诉我们如何做 16x16 并将结果存储在 32 位中。是的,实际上我的高斯系数是 16 位值。 【参考方案1】:

由于 8 位值是无符号的,因此您可以通过移位和屏蔽来执行此操作,就像您对标量代码所做的那样,例如

__m128i vrgba;

__m128i vr = _mm_and_si128(vrgba, _mm_set1_epi32(0xff));
__m128i vg = _mm_and_si128(_mm_srli_epi32(vrgba, 8), _mm_set1_epi32(0xff));
__m128i vb = _mm_and_si128(_mm_srli_epi32(vrgba, 16), _mm_set1_epi32(0xff));
__m128i va = _mm_srli_epi32(vrgba, 24);

请注意,我假设您的 RGBA 元素在 LS 8 位中具有 R 组件,在 MS 8 位中具有 A 组件,但如果它们是相反的字节序,您可以更改 vr/ vg/vb/va 向量。

【讨论】:

感谢保罗的工作,我想知道我们如何将其修改为 16 位打包而不是 32 位 您可以对 16 位执行非常相似的操作 - 显然您需要从两个输入向量开始。如果您在这方面需要进一步帮助,请发布一个新问题,要求提供 16 位解决方案并将其标记为 simd,我会想出一些办法(除非其他人胜过我)。 当然,我能够为 32 位执行此操作。我将首先查看性能因素,如果需要,我将使用我正在尝试实现的实际算法添加另一个问题。非常感谢你的帮助,因为很难找到关于它的好文档,所以我从 2 天开始就被困住了

以上是关于如何在 SSE 中解交织图像通道的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Matlab 中显示图像的红色通道?

如何选择RGB图像单色通道MATLAB?

如何使用 PIL 将 1 通道图像转换为 3 通道?

如何在 OpenCV 2 中从图像中获取通道数?

每隔一个字节快速复制到新的内存区域

Python:如何在 for 中解压缩多个值?