李海玲, 張昊
(西安航空學院 計算機學院, 西安 710077)
卷積[1-2]一詞最開始出現在信號與線性系統中,信號與線性系統中討論的就是信號經過一個線性系統以后發生的變化。而現實情況常常是一個信號前一時刻的輸出影響著這一時刻的輸出,所以一般利用系統的單位響應與系統的輸入求卷積,以得到系統的輸出信號。卷積定義為兩個變量在某范圍內相乘后求和的結果,如果卷積的變量是序列x(n)和h(n),則卷積的結果y(n)由式(1)得到式(1)。

*h(n)
(1)
其中星號*表示卷積。在數字圖像處理[3]和卷積神經網絡[4](Convolutional Neural Networks,簡稱CNN)等方面,卷積應用也非常廣泛,利用卷積運算可以對圖像進行空域增強,在卷積神經網絡的學習中,首當其沖的操作便是卷積。
數字圖像是一個二維的離散信號,對數字圖像做卷積操作就是利用卷積核(卷積模板)在圖像上滑動,將圖像點上的像素灰度值與對應的卷積核上的數值相乘,然后將所有相乘后的值相加作為卷積核中間像素對應的圖像上像素的灰度值,并最終滑動完所有圖像的過程,輸出結果仍然是一副圖像[5]。卷積具體過程,如圖1所示。

(a)*(b)=(c)
圖1 數字圖像卷積過程
其中圖1(a)為卷積前的圖像點上的像素灰度值,圖1(b)為卷積核,圖1(c)為卷積結果。
從圖像卷積過程可以看出,卷積操作會導致圖像變小,如圖1所示。原始圖像尺寸為5×5,卷積核尺寸為3×3,一次卷積結束卷積核移動步長為1個像素,卷積結果尺寸變為3×3。這是因為在卷積運算過程中要用到輸入圖像中與卷積核中心的鄰域所對應的像素,當卷積核滑到圖像邊界,比如圖像底部的像素,而它的下面已經沒有像素了,卷積核一部分數據則恰好落在了處理圖像的外圍,這樣就失去了與之相對應計算的數據。
解決這個問題有兩種辦法[5]:一種是忽略這些邊界處的像素,只考慮圖像內部與邊界距離小于等于卷積核半徑的像素。另一種是將輸入圖像進行擴展,使得卷積結果得到的圖像尺寸和輸入圖像尺寸一致。第一種辦法在原始圖像尺寸比較大且感興趣目標在圖像內部時常可以接受,因為此時圖像邊界損失不影響整體效果。然而如果卷積核移動步長增大或是卷積核變大,圖像邊界損失將愈加嚴重。所以經常的一種做法是人為的在卷積操作之前對圖像邊界進行擴展。
如前所述,當卷積核到達圖像邊界,為了得到和原始圖像大小相同的結果,降低圖像邊界損失,需要先對原始圖像做邊界擴展填充處理。邊界擴展填充處理需要解決兩個問題,第一,邊界擴展多少個像素;第二,擴展的邊界用什么值填充。
從圖(1)可知,邊界填充數量跟原始圖像尺寸、卷積核尺寸、移動步長均有關系。假設原始圖像尺寸為M×M,卷積核大小為N×N,邊緣填充像素個數為pad,移動步長為step。則卷積后圖像的尺寸m為式(2)。
m=(M-N+2×pad)/step+1
(2)
要得到m=M,即卷積前后的圖像尺寸不變,根據式(2),當給定卷積核移動步長,便可計算出邊界填充像素的個數。
確定好邊界填充的像素數目后,新增行或列中像素值可用不同的方法來確定。最簡單的方法就是全用0填充,缺點是有可能導致圖像邊界處有明顯的不連貫;或者用其在原圖像中4-鄰域像素的值填充,4個角上新增像素的值用其在原圖像中8-鄰域像素的值填充;或者將圖像在水平和垂直方向看作是周期循環的,最后一行(或列)之后是圖像的第一行(或列),從而用相應的行(或列)填充;或者利用外插技術,根據一定的規則進行邊界像素值填充[5]。
在卷積神經網絡中,邊界擴展的方法主要有邊界補0、邊界復制、邊界鏡像、邊界對稱和邊界塊復制等[6]。OpenCV的幫助文檔中提供了幾種不同的邊界擴展策略,如表1所示。

表1 OpenCV中邊界擴展類型及含義
其中“|”表示的是圖像的邊界,兩個“|”中間是圖像的內容,最后一個邊界拓展策略還要額外給定一個i值,表示用i值對邊界進行填充。
其中BORDER_REPLICATE體現的就是邊界復制的意思,BORDER_REFLECT表示用邊界鏡像方式填充,BORDER_REFLECT_101表示對稱填充,BORDER_WRAP表示邊界以塊復制填充,BORDER_CONSTANT表示用指定的常量i填充,當i=0時即為邊界補0的含義。
在OpenCV中,邊界擴展以原圖為基準,逐行處理,先擴展左邊界,再擴展右邊界,最后擴展上邊界和下邊界,以圖1(a)為例,邊界擴展2個像素,各種擴展后的圖像如圖2所示。

(a)

(b)

(c)

(d)

(e)
其中圖2(a)為邊界補0結果,圖2(b)為邊界復制結果,圖2(c)為邊界鏡像結果,圖2(d)為邊界對稱結果,圖2(e)為邊界塊復制結果。
如果邊界填充的像素數為1,則邊界復制和邊界鏡像的結果是相同的,為了區分每一種邊界擴展方法,在OpenCV中,選用高斯-拉普拉斯算子(Laplacian of Gaussian,簡稱LoG算子)作為卷積核,對圖像進行了邊界擴展測試和實現。LoG算子常用于數字圖像的邊緣提取和二值化,它把Gauss平滑濾波器和Laplacian銳化濾波器結合起來,先平滑掉噪聲,再進行邊緣檢測,所以效果會更好[7-9]。
OpenCV中用函數filter2D來實現對圖像或矩陣的卷積操作。這個函數本質上做的是協相關操作,但是當核算子是對稱的,則協相關操作也是卷積操作。copyMakeBorder函數的功能是設置邊界擴展的方式及填充值的數量。在對圖片進行卷積處理之前,先調用copyMakeBorder函數進行圖像邊界擴充,然后調用函數filter2D實現圖片卷積,最后再對卷積結果進行剪切,從而得到和原始圖片相同尺寸的對應卷積結果[10]。
實驗中選用標準原始圖像尺寸為512×512,卷積核為LoG算子,大小為5×5的模板,如圖3所示。

圖3 常用的高斯-拉普拉斯算子
移動步長設置為1,根據式(2),要得到原始圖像的尺寸,邊界填充像素個數為2。實驗結果,如圖4所示。
其中圖4(a)為邊界補0后的卷積結果,圖4(b)為邊界復制后的卷積結果,圖4(c)為邊界鏡像填充后的卷積結果,圖4(d)為邊界對稱填充后的卷積結果,圖4(e)為塊復制填充后的卷積結果,圖4(f)為原始圖像。

(a)

(b)

(c)

(d)

(e)

(f)
由于圖像邊緣只填充了2個像素,不同邊界填充的卷積結果肉眼不易區分,實驗結果數據,如圖5所示。






圖5 不同邊界擴充結果和卷積結果數據
為了說明情況,圖中只列出了圖像最前面的36個數據。其中6 × 6(前)表示原始圖像的前36個數據,6 × 6(后)表示原始圖像前6行、倒數6列的36個數據。實驗數據給出了五種不同邊界擴充方法的結果以及每一種方法擴充后的卷積結果。
卷積是數字圖像處理和卷積神經網絡中常用的一個技術,卷積操作會導致圖像變小從而損失圖像邊界。為得到和原始圖像尺寸相同的卷積結果,本文研究了各種邊界擴展方法及填充方式,并在OpenCV中以高斯-拉普拉斯算子為卷積核,對標準圖像進行了各種邊界填充的實現以及對應的卷積實現和裁剪,為進一步開展卷積神經網絡研究和深度學習奠定基礎。