【问题标题】:Create a matrix of neighbours创建邻居矩阵
【发布时间】:2018-08-10 21:55:07
【问题描述】:

我有一个稀疏矩阵,我需要为每个索引创建一个新的邻居矩阵。

下面我将数据表示在NxM 矩阵中。对于矩阵的每个元素,我需要在KxK 的一部分中获取邻居。有了这些信息,它将生成一个NMxKK 矩阵,该矩阵在每一行中都包含元素的相邻 KK 的索引。

前段时间我问过类似的question,但不同的是现在数据是结构化的,所以我可以不用KdTree。

这个新矩阵用于计算非零邻居的距离,并用这些距离为每个邻居关联一个权重,最终将期望值估计为邻居的weighted average

提前致谢!

更新

我有图像中的数据(使用函数generate_data生成),我需要执行以下操作。

给定一个过滤器/内核/NxN 矩阵,N 是我定义的内核大小,计算非零值相对于中心像素的距离。以图像的(1, 8) 位置的值20 为例。取5x5 的矩阵,感兴趣的非零值是40(0, 6))、37(1, 6))和25(3, 10)),距离2.23606798,分别为22.82842712(在索引之间进行欧几里得范数)。

这一步我需要得到的是矩阵res

[[0.         2.23606798 2.         0.         0.        ]
 [0.         0.         0.         0.         0.        ]
 [0.         0.         1.         0.         0.        ]
 [0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         2.82842712]]

我还需要获取矩阵中心的1.,以同时考虑我站立的位置(与自身的距离为0.)。

使用这些值,我得到具有非零值的掩码并根据高斯分布计算权重:

import scipy.stats as st 
mask = 0 < res
gauss = st.norm.pdf(res) # or st.norm.pdf(mask * kernel(5))

[[0.        , 0.03274718, 0.05399097, 0.        , 0.        ],
 [0.        , 0.        , 0.        , 0.        , 0.        ],
 [0.        , 0.        , 0.39894228, 0.        , 0.        ],
 [0.        , 0.        , 0.        , 0.        , 0.        ],
 [0.        , 0.        , 0.        , 0.        , 0.00730688]])

total = gauss.sum() # 0.4929873057962355

最后,使用这些权重,我通过插值计算像素的权重和最终值。

val[1, 8] = 0.03274718 * 40 / total + 0.05399097 * 37 / total + 0.39894228 * 20 / total + 0.00730688 * 25 / total

我必须为每个像素做同样的事情(我想我必须添加一个kernel_size padding // 2 才能使用整个数组)。

这是我的脚本

import matplotlib.pylab as plt
import numpy as np
import scipy.stats as st

from scipy import sparse


def generate_data(m, n, density):
    s = 64 * sparse.random(m, n, density=density).A
    return s.astype(np.int8)


def plot_matrix(matrix):
    for (j, i), label in np.ndenumerate(s):
        plt.text(i, j, label, ha='center', va='center')

    plt.imshow(matrix)
    plt.show()


def kernel(n):
    n = n if n % 2 != 0 else n + 1
    mid = n // 2

    m = np.ndarray((n, n, 2))
    for i in range(n):
        for j in range(n):
            m[i, j] = np.array([i, j])

    return np.linalg.norm(m - [mid, mid], axis=2)


s = generate_data(10, 14, 0.25)
plot_matrix(s)

【问题讨论】:

  • 您好!当您在这里提出问题时,如果您提供一个最小的、可验证的完整示例 (MVCE),它真的很有帮助(并且可能会更快地为您提供答案):这只是这里人们的起点想帮助你。这样我们就可以直接复制/粘贴代码并直接解决问题,而无需对您真正要问的问题进行疯狂的猜测。
  • 你说得对。我通常会添加示例,但从那个角度来看我没有想到它。这次我没有添加 MVCE,因为矩阵非常大,但现在我将用一个最小示例更新我的问题
  • 我已经更新了我的问题!

标签: python numpy scipy interpolation


【解决方案1】:

这真的很简单,虽然可能效率不高。我要做的是两个卷积:

  • 首先,它是高斯核与矩阵的卷积

    conv_1 = convolve2d(m * mask_clean, k_gauss)

  • 第二个,带掩码的高斯核

    conv_2 = convolve2d(mask_clean, k_gauss)

在每个位置,conv_1 将具有由高斯核的相应因子加权的每个值的总和。 conv_2 将在每个位置具有所有非零值的总和。剩下要做的就是将它们分开以获得最终结果

# m have the data
mask_clean = (0 < m) & (m_mean - 3*m_std < m) & (m < m_mean + 3*m_std)

# Custom function to create a gaussian kernel
k = gkern(kernlen=5, std=5//2)
k_gauss = st.norm.pdf(k)

conv_1 = convolve2d(m * mask_clean, k_gauss)
conv_2 = convolve2d(mask_clean, k_gauss)
final = conv_1 / conv_2

【讨论】:

    猜你喜欢
    • 2016-04-06
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多