二维离散卷积之可分离卷积核

学习资料参考:

张平.《OpenCV算法精解:基于Python与C++》.[Z].北京.电子工业出版社.2017.


概念

类比于线性代数中的两个矩阵的乘法运算。如果一个卷积核至少由两个尺寸比它小的卷积核full卷积而成,如下所示:
在这里插入图片描述
那么这样的卷积核就可以分离。上述例子是分离为一维水平方向和一维垂直方向上的卷积核。当分离的一般不满足交换律。


性质

  1. full卷积
    若卷积核可分离,那么我们进行卷积的时候,可以按照分离后,再进行卷积,如下所示:
    在这里插入图片描述

一般的卷积计算如下:
I = ( 1 2 3 10 12 32 43 12 4 190 12 234 78 0 12 43 90 32 8 90 71 12 4 98 123 ) I = {(\begin{matrix} 1 & 2 & 3 & 10 &12\\ 32 & 43 & 12&4&190 \\ 12 & 234 &78&0&12\\ 43&90&32&8&90\\ 71&12&4&98&123 \end{matrix})} I=(1321243712432349012312783241040898121901290123)
k e r n e l = ( 1 0 − 1 1 0 − 1 1 0 − 1 ) kernel = {(\begin{matrix} 1 & 0 & -1 \\ 1& 0& -1 \\ 1 & 0 & -1 \end{matrix})} kernel=(111000111).

计算两者的卷积
I_Kernel = signal.convolve2d(I,kernel,mode = 'full',boundary = 'fill',fillvalve = 0);

进行分离后再卷积,如下所示:
k e r n e l = ( 1 1 1 ) kernel = {(\begin{matrix}1 \\1 \\1 \end{matrix})} kernel=(111)* ( 1 0 − 1 ) {(\begin{matrix} 1 &0 &-1 \end{matrix})} (101)
或者
k e r n e l = ( 1 0 − 1 ) kernel = {(\begin{matrix}1 \\0 \\-1 \end{matrix})} kernel=(101)* ( 1 1 1 ) {(\begin{matrix} 1 &1 &1 \end{matrix})} (111)

再次计算两者的卷积

kernel1 = np.array([[1],[1],[1]],np.float32)
kernel2 = np.array([[1,0,-1]],np.float32)
I_k1 = signal.convolve2d(I,kernel1,mode = 'full',boundary = 'fill',fillvalve = 0)
I_k1_k2 = signal.convolve2d(I_k1 ,kernel2,mode = 'full',boundary = 'fill',fillvalve = 0)
  1. same卷积
    与full卷积类似,拆分也类似。
    代码改动,将mode参数修改为same即可
kernel1 = np.array([[1],[1],[1]],np.float32)
kernel2 = np.array([[1,0,-1]],np.float32)
I_same1 = signal.convolve2d(I,kernel1,mode = 'same',boundary = 'fill',fillvalve = 0)
I_same2 = signal.convolve2d(I_same1,kernel2,mode = 'same',boundary = 'fill',fillvalve = 0)

可分离卷积的优势

可使卷积运算量减少。
如图像矩阵 I I I的尺寸为高 H 1 H1 H1,宽 W 1 W1 W1,卷积核kernel的尺寸为高 H 2 H2 H2,宽 W 2 W2 W2,那么进行same卷积的运算量预估为 ( H 1 ∗ W 1 ) ∗ ( H 2 ∗ W 2 ) (H1 * W1)*(H2 * W2) H1W1H2W2次;若进行分离,那么卷积核就转换为一个行向量与一个列向量,然后再进行运算,可使卷积运算量减少到 ( H 1 ∗ W 1 ) ∗ ( H 2 + W 2 ) (H1 * W1)*(H2 + W2) H1W1H2+W2

猜你喜欢

转载自blog.csdn.net/qq_44116998/article/details/124067207