【问题标题】:Decompose 2D filter kernel into 1D kernels将 2D 滤波器内核分解为 1D 内核
【发布时间】:2018-07-07 12:00:49
【问题描述】:

我正在尝试将二维矩阵分成两个向量,以使它们的外积等于原始矩阵。

使用 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

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

该应用程序用于分解内核,因此我可以应用两次 1D 卷积来加速。我也在 python 中尝试了this answer,但没有成功。

【问题讨论】:

  • 我不认为 DoG 是可分离的(尽管 SVD 应该可以工作并报告几个非零值),但没有什么禁止分离计算两个高斯并减去。

标签: python image-processing


【解决方案1】:

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

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

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

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

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

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

要知道二维内核是否可分离,请计算其rank:秩必须为 1。这表明所有行都是彼此的缩放版本。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 2019-01-03
    • 2017-07-25
    • 2021-01-07
    • 2014-05-27
    • 2011-06-09
    相关资源
    最近更新 更多