C語言實現矩陣卷積運算

直觀的說卷積操作可以理解爲——每次透過一個較小的「窗口」去覆蓋被輸入進來的大窗口中的某一部分所得出的結果。每次得出結果後小窗口就會根據步長滑動至下一個位置並重復這一計算過程,最終得到卷積後的輸出矩陣結果。

卷積的計算過程可由下圖直觀說明。
在這裏插入圖片描述
必須注意的是,根據卷積的數學原理,上圖中的3*3矩陣實際上是真正卷積核矩陣經逆時針旋轉180度所得到的矩陣。再舉一詳細示例加以說明。
假設卷積核爲:
在這裏插入圖片描述
待處理矩陣爲:
在這裏插入圖片描述
則首先應該將卷積核逆時針旋轉180度得到如下矩陣:
在這裏插入圖片描述
再將卷積核h的中心對準x的第一個元素,然後h和x重疊的元素相乘,h中不與x重疊的地方x用0代替,再將相乘後h對應的元素相加,得到結果矩陣中Y的第一個元素。比如結果矩陣中第一個數字即爲下圖所示的矩陣運算得出,結果爲16。
在這裏插入圖片描述
值得注意的是矩陣卷積運算實際上分爲三種不同的計算情況,將會導致卷積後的輸出矩陣大小不同。說明如下。
1、same mode:即如上面所舉例子中的重合方法,將卷積核的中心從輸入矩陣左上角的第一個數字開始重合,再依次與每一個位置重合。對於輸入中外圍本不存在的部分需要用0填充。
在這裏插入圖片描述
2、full mode:以卷積核右下角的數字與輸入矩陣左上角的第一個數字開始重合,再依次計算。填充方法相同。
在這裏插入圖片描述
3、valid mode:卷積核整個在輸入圖像的內部進行重合計算。

在這裏插入圖片描述
綜上所述代碼實現卷積操作時我們需要完成矩陣旋轉後再進行矩陣相乘操作,並對不同計算情況做出相應計算方法。
首先對矩陣做出定義。
typedef struct Mat2DSize{
int c; // 列(寬)
int r; // 行(高)
}nSize;
然後編寫矩陣旋轉180函數。
在這裏插入圖片描述
再來是矩陣擴充函數。
在這裏插入圖片描述

然後根據三種不同情況進行矩陣對應位置相乘再累加操作如下
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

最後卷積函數如下:
在這裏插入圖片描述
主函數調用上述函數進行卷積運算,如下圖。

在這裏插入圖片描述
運算結果如下,經驗證正確。
在這裏插入圖片描述