我们将首先实现一维卷积,然后对其进行矢量化。2-D 矢量化卷积将在各行之间执行 1-D 卷积以产生正确的结果。
一维卷积:标量
void conv1d(Mat src, Mat &dst, Mat 内核)
{
int len = src.cols;
dst = Mat(1, len, CV_8UC1);
int sz = kernel.cols / 2;
copyMakeBorder(src, src, 0, 0, sz, sz, BORDER_REPLICATE);
for (int i = 0; i < len; i++)
{
double 值 = 0;
for (int k = -sz; k <= sz; k++)
值 += src.ptr(0)[i + k + sz] * kernel.ptr(0)[k + sz];
dst.ptr(0)[i] = saturate_cast(值);
}
}
-
我们首先设置变量并在 src 矩阵的两侧创建边框,以处理边缘情况。
int len = src.cols;
dst = Mat(1, len, CV_8UC1);
int sz = kernel.cols / 2;
copyMakeBorder(src, src, 0, 0, sz, sz, BORDER_REPLICATE);
-
对于主循环,我们选择一个索引 i,并使用 k 变量将其与内核一起偏移。我们将值存储在 value 中,并将其添加到 dst 矩阵中。
for (int i = 0; i < len; i++)
{
double 值 = 0;
for (int k = -sz; k <= sz; k++)
值 += src.ptr(0)[i + k + sz] * kernel.ptr(0)[k + sz];
dst.ptr(0)[i] = saturate_cast(值);
}
一维卷积:矢量
我们现在将看一维卷积的矢量化版本。
void conv1dsimd(Mat src, Mat 内核, float *ans, int row = 0, int rowk = 0, int len = -1)
{
如果 (len == -1)
len = src.cols;
Mat src_32,kernel_32;
const int alpha = 1;
src.convertTo(src_32, CV_32FC1, alpha);
int ksize = kernel.cols, sz = kernel.cols / 2;
copyMakeBorder(src_32, src_32, 0, 0, sz, sz, BORDER_REPLICATE);
<