创建一个邻居矩阵
Create a matrix of neighbours
我有一个稀疏矩阵,我需要为每个索引创建一个新的邻域矩阵。
下面我在 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
、2
和 2.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)
这真的很简单,虽然可能不是很有效。我要做的是两个卷积:
首先是高斯核与矩阵卷积
conv_1 = convolve2d(m * mask_clean, k_gauss)
第二种,带mask的高斯核
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
我有一个稀疏矩阵,我需要为每个索引创建一个新的邻域矩阵。
下面我在 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
、2
和 2.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)
这真的很简单,虽然可能不是很有效。我要做的是两个卷积:
首先是高斯核与矩阵卷积
conv_1 = convolve2d(m * mask_clean, k_gauss)
第二种,带mask的高斯核
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