我试图把一个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为什么我不能分解这个矩阵?哪一类矩阵是可分的(分为两个向量)?
这个应用程序是用来分解一个内核的,所以我可以应用两道一维卷积来加速。我还在python中尝试了这个答案,但没有成功。
发布于 2018-07-07 14:05:06
为什么我不能分解这个矩阵?
因为它是不可分离的。DoG和许多其他内核是不可分离的。
哪一类矩阵是可分的(分为两个向量)?
所有行都是缩放版本的其他行的内核是可分离的。也就是说,每一行i必须为窗体。
r[i][j] = a[i] * b[j]其中b是“模型行”,而a[i]是每一行的缩放。这看起来很明显,因为上面的乘法是当您将列内核a与行内核b (以及问题中的代码使用的外部产品)合并时得到的。
要知道一个2D内核是否是可分离的,计算它的排名:秩必须是1。这意味着所有的行都是彼此缩放的版本。
作为参考,这里有两个不同的MATLAB解决方案,用于任意维数的内核分解:
https://stackoverflow.com/questions/51223006
复制相似问题