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('
');
% 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('
');
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 ("
other 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