将2D过滤器内核分解为1D内核

时间:2018-07-07 12:00:50

标签: python image-processing

我正在尝试将2D矩阵分为两个向量,以使其外积等于原始矩阵。

使用SVD:

import cv2
import numpy as np

def createDoG(sigma, sigmaRatio=0.5):
    size = int(np.ceil(sigma*3))*2+1
    kernel1_2D = np.outer(cv2.getGaussianKernel(size, sigma), cv2.getGaussianKernel(size, sigma))
    kernel2_2D = np.outer(cv2.getGaussianKernel(size, sigma*sigmaRatio), cv2.getGaussianKernel(size, sigma*sigmaRatio))
    return kernel1_2D - kernel2_2D

def decompose(kernel):
    U, S, V = np.linalg.svd(kernel)
    h1 = U[:,0] * np.sqrt(S[0])
    h2 = V[0] * np.sqrt(S[0])
    return h1,h2

kernel_DoG = createDoG(1)
h1,h2 = decompose(kernel_DoG)
print("kernel_DoG == h1*h2':", np.isclose(kernel_DoG, np.outer(h1, h2)).all()) #prints False

为什么我不能分解这个矩阵?哪类矩阵是可分离的(分为两个向量)?

该应用程序用于分解内核,因此我可以应用两遍一维卷积以加快速度。我也尝试过this answer在python中没有运气。

1 个答案:

答案 0 :(得分:1)

  

为什么我不能分解这个矩阵?

因为它不可分离。 DoG和许多其他内核是不可分离的。

  

哪些类别的矩阵是可分离的(分为两个向量)?

所有行都是其他行的可缩放版本的内核是可分离的。也就是说,每行i的格式都必须

r[i][j] = a[i] * b[j]

其中b是“模型行”,而a[i]是每一行的缩放比例。这看起来很明显,因为上面的乘法是将列内核a与行内核b卷积时得到的结果(并且是问题代码使用的外部乘积)。 / p>

要知道2D内核是否可分离,请计算其rank:等级必须为1。这表示所有行都是彼此缩放的版本。

作为参考,以下是任意数量维的两种不同的MATLAB内核分解解决方案: