MATLAB filter2 和 conv2 函數說明
在 MATLAB 中,filter2 函數實現二維數字濾波器.conv2 函數實現二維卷積.
filter2(H, X, mode) 等價於 conv2(X, rot90(H,2), mode). 其中,H 表示有理傳遞函數的系數(Coefficients of rational transfer function),即常說的濾波器核或卷積核.X 表示輸入數據.mode 表示卷積或濾波所采用的模式,其決定了返回數據的長度,以及結果數據的不同部分.共有三種模式:'full', 'same', 'valid',具體含義詳見 filter2 函數的 shape 參數文檔說明,或查看我的博文 相關與卷積(數字信號處理)的數學原理及 Python 實現 的原理部分.
注:MATLAB 中,B = rot90(A, k) 將數組 A 逆時針旋轉 k*90 度,其中 k 為整數.
Python 中的等價函數
在 Python 中,MATLAB filter2 的等價函數是 scipy.signal.correlate2d;MATLAB conv2 的等價函數是 scipy.signal.convolve2d.
具體來說,filter2(H, X, mode) 等價於 scipy.signal.correlate2d(X, H, mode);conv2(X, H, mode) 等價於 scipy.signal.convolve2d(X, H, mode).
注意,filter2(MATLAB) 與 scipy.signal.correlate2d的輸入參數 H, X 的順序是不一致的.
如果二維濾波或卷積結果采用常用的 'same' 模式,還可以使用 Python 中的 cv2.filter2D (OpenCV模塊), scipy.ndimage.correlate 和 scipy.ndimage.convolve 替代.對於二維濾波('same'模式)的具體用法為
cv2.filter2D(X, -1, H, borderType=cv2.BORDER_CONSTANT)
scipy.ndimage.correlate(X, H, mode='constant', cval=0.0)
scipy.ndimage.convolve(X, np.rot90(H,2), mode='constant', cval=0.0)
示例
MATLAB 代碼
X = [1 2 3]; % input data H = [4 5 6]; % kernel % display filter2() results disp('filter2 results'); fprintf('full: '); disp(filter2(H, X, 'full')); fprintf('same: '); disp(filter2(H, X, 'same')); fprintf('valid: '); disp(filter2(H, X, 'valid')); fprintf('\n'); % display conv2() results disp('conv2 results'); fprintf('full: '); disp(conv2(H, X, 'full')); fprintf('same: '); disp(conv2(H, X, 'same')); fprintf('valid: '); disp(conv2(H, X, 'valid')); fprintf('\n');
Python 代碼
import numpy as np import scipy.ndimage import scipy.signal import cv2 X = np.array([1, 2, 3]).reshape(1,3) # input data
H = np.array([4, 5, 6]).reshape(1,3) # kernel
# display scipy.signal.correlate2 results
print ("scipy.signal.correlate2d results") print ("full: {}".format(scipy.signal.correlate2d(X, H, 'full'))) print ("same: {}".format(scipy.signal.correlate2d(X, H, 'same'))) print ("valid: {}".format(scipy.signal.correlate2d(X, H, 'valid'))) print ('') # display scipy.signal.convolve2 results
print ("scipy.signal.convolve2d results") print ("full: {}".format(scipy.signal.convolve2d(X, H, 'full'))) print ("same: {}".format(scipy.signal.convolve2d(X, H, 'same'))) print ("valid: {}".format(scipy.signal.convolve2d(X, H, 'valid'))) # others
print ("\nother filters in Python ('same' mode)") print ("cv2.filter2D: {}".format(cv2.filter2D(X.astype('float32'), -1, H, borderType=cv2.BORDER_CONSTANT))) print ("scipy.ndimage.correlate: {}".format(scipy.ndimage.correlate(X, H, mode='constant', cval=0.0))) print ("scipy.ndimage.convolve: {}".format(scipy.ndimage.convolve(X, np.rot90(H,2), mode='constant', cval=0.0)))
注:cv2.filter2D 在 OpenCV 3.4.0 中,不支持整數類型的輸入數據,需要先轉為浮點型如 'float32' 等,才能正確執行.
參考資料
1. Equivalent of Matlab filter2(filter, image, 'valid') in python. https://stackoverflow.com/questions/43270274/equivalent-of-matlab-filter2filter-image-valid-in-python
2. Equivalent function of matlabs filter2 in opencv. https://stackoverflow.com/questions/29212944/equivalent-function-of-matlabs-filter2-in-opencv
3. What is the difference between conv2, filter2 and imfilter..? https://www.mathworks.com/matlabcentral/answers/17529-what-is-the-difference-between-conv2-filter2-and-imfilter