gpt4 book ai didi

python - 如何在 Python 中高效计算两个高斯分布的热图?

转载 作者:行者123 更新时间:2023-12-02 15:09:12 25 4
gpt4 key购买 nike

我正在尝试生成一个热图,其中像素值由两个独立的二维高斯分布控制。设它们分别为 Kernel1 (muX1, muY1, sigmaX1, sigmaY1) 和 Kernel2 (muX2, muY2, sigmaX2, sigmaY2)。更具体地说,每个内核的长度是其标准差的三倍。第一个内核有 sigmaX1 = sigmaY1,第二个内核有 sigmaX2 < sigmaY2。两个核的协方差矩阵都是对角线的(X 和 Y 是独立的)。 Kernel1 通常完全在 Kernel2 中。

我尝试了以下两种方法,结果都不理想。有人可以给我一些建议吗?

方法一:

迭代 map 上的所有像素值对 (i, j) 并计算由 I(i,j) = P(i, j | Kernel1, Kernel2) = 1 给出的 I(i,j) 的值 - (1 - P(i, j | Kernel1)) * (1 - P(i, j | Kernel2))。然后得到了如下结果,从平滑度上来说还是不错的。但是在我的电脑上运行需要10秒,太慢了。

代码:

def genDensityBox(self, height, width, muY1, muX1, muY2, muX2, sigmaK1, sigmaY2, sigmaX2):
densityBox = np.zeros((height, width))
for y in range(height):
for x in range(width):
densityBox[y, x] += 1. - (1. - multivariateNormal(y, x, muY1, muX1, sigmaK1, sigmaK1)) * (1. - multivariateNormal(y, x, muY2, muX2, sigmaY2, sigmaX2))
return densityBox

def multivariateNormal(y, x, muY, muX, sigmaY, sigmaX):
return norm.pdf(y, loc=muY, scale=sigmaY) * norm.pdf(x, loc=muX, scale=sigmaX)

First approach

方法 2:

分别生成对应两个内核的两幅图像,然后使用一定的alpha值将它们混合在一起。每个图像都是通过取两个一维高斯滤波器的外积生成的。然后得到如下结果,很粗糙。但这种方法的优点是速度非常快,因为在两个向量之间使用了外积。 Second approach

由于第一个很慢,第二个很粗糙,我试图找到一种同时实现良好平滑度和低时间复杂度的新方法。有人可以帮我吗?

谢谢!

对于第二种方法,二维高斯图可以很容易地生成,如前所述here :

def gkern(self, sigmaY, sigmaX, yKernelLen, xKernelLen, nsigma=3):
"""Returns a 2D Gaussian kernel array."""
yInterval = (2*nsigma+1.)/(yKernelLen)
yRow = np.linspace(-nsigma-yInterval/2.,nsigma+yInterval/2.,yKernelLen + 1)
kernelY = np.diff(st.norm.cdf(yRow, 0, sigmaY))
xInterval = (2*nsigma+1.)/(xKernelLen)
xRow = np.linspace(-nsigma-xInterval/2.,nsigma+xInterval/2.,xKernelLen + 1)
kernelX = np.diff(st.norm.cdf(xRow, 0, sigmaX))
kernelRaw = np.sqrt(np.outer(kernelY, kernelX))
kernel = kernelRaw / (kernelRaw.sum())
return kernel

最佳答案

你的方法很好,除了你不应该遍历 norm.pdf 而只是推送你想要内核评估的所有值,然后将输出 reshape 为所需的图像的形状。

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import multivariate_normal

# create 2 kernels
m1 = (-1,-1)
s1 = np.eye(2)
k1 = multivariate_normal(mean=m1, cov=s1)

m2 = (1,1)
s2 = np.eye(2)
k2 = multivariate_normal(mean=m2, cov=s2)

# create a grid of (x,y) coordinates at which to evaluate the kernels
xlim = (-3, 3)
ylim = (-3, 3)
xres = 100
yres = 100

x = np.linspace(xlim[0], xlim[1], xres)
y = np.linspace(ylim[0], ylim[1], yres)
xx, yy = np.meshgrid(x,y)

# evaluate kernels at grid points
xxyy = np.c_[xx.ravel(), yy.ravel()]
zz = k1.pdf(xxyy) + k2.pdf(xxyy)

# reshape and plot image
img = zz.reshape((xres,yres))
plt.imshow(img); plt.show()

enter image description here

这种方法不应该花太长时间:

In [26]: %timeit zz = k1.pdf(xxyy) + k2.pdf(xxyy)
1000 loops, best of 3: 1.16 ms per loop

关于python - 如何在 Python 中高效计算两个高斯分布的热图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44945111/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com