我正在尝试将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中没有运气。
答案 0 :(得分:1)
为什么我不能分解这个矩阵?
因为它不可分离。 DoG和许多其他内核是不可分离的。
哪些类别的矩阵是可分离的(分为两个向量)?
所有行都是其他行的可缩放版本的内核是可分离的。也就是说,每行i
的格式都必须
r[i][j] = a[i] * b[j]
其中b
是“模型行”,而a[i]
是每一行的缩放比例。这看起来很明显,因为上面的乘法是将列内核a
与行内核b
卷积时得到的结果(并且是问题代码使用的外部乘积)。 / p>
要知道2D内核是否可分离,请计算其rank:等级必须为1。这表示所有行都是彼此缩放的版本。
作为参考,以下是任意数量维的两种不同的MATLAB内核分解解决方案: