C语言实现矩阵卷积运算

直观的说卷积操作可以理解为——每次透过一个较小的“窗口”去覆盖被输入进来的大窗口中的某一部分所得出的结果。每次得出结果后小窗口就会根据步长滑动至下一个位置并重复这一计算过程,最终得到卷积后的输出矩阵结果。

卷积的计算过程可由下图直观说明。
C语言实现矩阵卷积运算
必须注意的是,根据卷积的数学原理,上图中的3*3矩阵实际上是真正卷积核矩阵经逆时针旋转180度所得到的矩阵。再举一详细示例加以说明。
假设卷积核为:
C语言实现矩阵卷积运算
待处理矩阵为:
C语言实现矩阵卷积运算
则首先应该将卷积核逆时针旋转180度得到如下矩阵:
C语言实现矩阵卷积运算
再将卷积核h的中心对准x的第一个元素,然后h和x重叠的元素相乘,h中不与x重叠的地方x用0代替,再将相乘后h对应的元素相加,得到结果矩阵中Y的第一个元素。比如结果矩阵中第一个数字即为下图所示的矩阵运算得出,结果为16。
C语言实现矩阵卷积运算
值得注意的是矩阵卷积运算实际上分为三种不同的计算情况,将会导致卷积后的输出矩阵大小不同。说明如下。
1、same mode:即如上面所举例子中的重合方法,将卷积核的中心从输入矩阵左上角的第一个数字开始重合,再依次与每一个位置重合。对于输入中外围本不存在的部分需要用0填充。
C语言实现矩阵卷积运算
2、full mode:以卷积核右下角的数字与输入矩阵左上角的第一个数字开始重合,再依次计算。填充方法相同。
C语言实现矩阵卷积运算
3、valid mode:卷积核整个在输入图像的内部进行重合计算。

C语言实现矩阵卷积运算
综上所述代码实现卷积操作时我们需要完成矩阵旋转后再进行矩阵相乘操作,并对不同计算情况做出相应计算方法。
首先对矩阵做出定义。
typedef struct Mat2DSize{
int c; // 列(宽)
int r; // 行(高)
}nSize;
然后编写矩阵旋转180函数。
C语言实现矩阵卷积运算
再来是矩阵扩充函数。
C语言实现矩阵卷积运算

然后根据三种不同情况进行矩阵对应位置相乘再累加操作如下
C语言实现矩阵卷积运算
C语言实现矩阵卷积运算
C语言实现矩阵卷积运算

最后卷积函数如下:
C语言实现矩阵卷积运算
主函数调用上述函数进行卷积运算,如下图。

C语言实现矩阵卷积运算
运算结果如下,经验证正确。
C语言实现矩阵卷积运算