C 如何将3x3的卷积核与图像相乘
有一个3x3的卷积核和一个由整数值像素数组表示的图像 卷积核表示如下:C 如何将3x3的卷积核与图像相乘,c,c++11,sse,simd,intrinsics,C,C++11,Sse,Simd,Intrinsics,有一个3x3的卷积核和一个由整数值像素数组表示的图像 卷积核表示如下: //compound convolutional kernels // | 1, 0, 1| // convolutional kernel H = src x | 0, 0, 0| // |-1, 0, -1| // | 1, 0,
//compound convolutional kernels
// | 1, 0, 1|
// convolutional kernel H = src x | 0, 0, 0|
// |-1, 0, -1|
// | 1, 0, -1|
// convolutional kernel V = src x | 0, 0, 0|
// | 1, 0, -1|
卷积核=核H+核V
for(int inc=0; inc<height-2; inc++)
{
//loaded 3 lines into memory
str1_16pxs = _mm_loadu_si128((__m128i*)(src_all_str));
str2_16pxs = _mm_loadu_si128((__m128i*)(src2_all_str));
str3_16pxs = _mm_loadu_si128((__m128i*)(src3_all_str));
//packing 16bit
str1_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str1_16pxs);
str2_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str2_16pxs);
str3_16pxs_pack1st_8to16 = _mm_cvtepu8_epi16(str3_16pxs);
//---!
//there is we make the first convolution for 8px's
//... How ???
//---
//summ 1st 8to16 vertical registers
sum1_str12_vert_16pxs_pack1st_8to16 = _mm_add_epi16(str1_16pxs_pack1st_8to16, str2_16pxs_pack1st_8to16);
sum1_str123_vert_16pxs_pack1st_8to16 = _mm_add_epi16(sum1_str12_vert_16pxs_pack1st_8to16,str3_16pxs_pack1st_8to16);
for(int jnc=0; jnc<(width >> 4); jnc++)
{
str1_16pxs_plus_8pxs = _mm_srli_si128(str1_16pxs, 8);
str2_16pxs_plus_8pxs = _mm_srli_si128(str2_16pxs, 8);
str3_16pxs_plus_8pxs = _mm_srli_si128(str3_16pxs, 8);
//pack 2nd 8to16 registers (+8px's)
str1_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str1_16pxs_plus_8pxs);
str2_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str2_16pxs_plus_8pxs);
str3_16pxs_pack2nd_8to16 = _mm_cvtepu8_epi16(str3_16pxs_plus_8pxs);
//---!
//do convolution for the remaining 8px's and so on until the end of the read line
//... How ???
//---
//summ vertic 8to16 registers
sum1_str12_vert_16pxs_pack2nd_8to16 = _mm_add_epi16(str1_16pxs_pack2nd_8to16, str2_16pxs_pack2nd_8to16);
sum1_str123_vert_16pxs_pack2nd_8to16 = _mm_add_epi16(sum1_str12_vert_16pxs_pack2nd_8to16,str3_16pxs_pack2nd_8to16);
//---!4 loading next 16 px's
src_all_str += 16;
src2_all_str += 16;
src3_all_str += 16;
//...
_mm_store_si128((__m128i*)(dst_all_str), res);
dst_all_str += 8;
}//for(jnc)
}//for(inc)
for(int inc=0;incSo,示例代码:
void SSEcode_Conv3x3 (unsigned char *src, int width, int height, short *dst)
{
// Assert that width is a multiple of 16
if (width & 0xF) return;
unsigned char* src_line1 = src;
unsigned char* src_line3 = src + 2 * width;
__m128i zero = _mm_setzero_si128();
for (int i = 0; i < height - 2; i++)
{
__m128i line1 = _mm_load_si128((__m128i*)src_line1);
__m128i line3 = _mm_load_si128((__m128i*)src_line3);
for (int j = 0; j < width / 16 - 1; j++)
{
src_line1 += 16;
src_line3 += 16;
__m128i line1next = _mm_load_si128((__m128i*)src_line1);
__m128i line3next = _mm_load_si128((__m128i*)src_line3);
//blablabla
#ifdef USE_CORE_H
_mm_add_epi16
_mm_add_epi16
_mm_sub_epi16
#endif
//blablabla
_mm_store_si128((__m128i*)(dst + 8), res);
line1 = line1next;
line3 = line3next;
dst += 16;
}//for (j)
src_line1 += 16;
src_line3 += 16;
//blablabla
_mm_store_si128((__m128i*)(dst + 8), res);
dst += 16;
}//for (i)
}
void SSEcode_Conv3x3(无符号字符*src,整型宽度,整型高度,短*dst)
{
//断言宽度是16的倍数
if(宽度&0xF)返回;
无符号字符*src_line1=src;
无符号字符*src_line3=src+2*宽度;
__m128i零=_mm_setzero_si128();
对于(int i=0;i
编写代码花了很长时间。
我是新来的,所以很遗憾,一个精通CE的人并没有帮助我学习(问题是什么?wierd中间部分是什么?在代码中查看://--!//--我们对8px进行了第一次卷积//…如何?//--代码是代码。问题和描述你所拥有的/你想要的应该放在文本中。请阅读,特别是关于家庭作业问题的链接。你如何解释?在那里是一个由整数值表示的像素数组。有一个卷积3x3的核心。有必要在我从数组中读取三行后处理卷积的核心。我不知道如何处理整数值卷积数组的核心。在“如何?”我指明了执行此操作的位置。您是否有复制/粘贴错误?您的代码甚至无法编译您自己有一行\u mm\u add\u epi16
,没有参数。Peter Cordes这是示例代码。)代码需要342行。那么这不是你问题的答案。为什么你甚至在没有链接到你的实际实现的情况下发布这篇文章?这对任何在寻找3x3图像卷积时发现这篇问答的人都没有任何用处。例如,Peter Cordes,我可以写一篇关于该做什么的抽象解释。请使用你的编辑链接您的问题可添加其他信息。仅当完整回答问题时,才可使用“发布答案”按钮-