- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个 numpy 数组形式的大图像(opencv 将其作为 3 个 uint8 值的二维数组返回)并想为每个像素计算高斯内核的总和,即(SO 中仍然没有 LaTeX 支持吗? ):
对于具有指定权重 w 的 N 个不同内核,均值和对角协方差矩阵。
所以基本上我想要一个函数 compute_densities(image, kernels) -> numpy array of floats
.在 python 中有效执行此操作的最佳方法是什么?如果 scipy 中还没有一个库函数,我会感到惊讶,但很久以前我在 uni 有统计数据,所以我确实对文档的细节有点困惑..
基本上我想要以下内容,只是比简单的 python 更有效(2pi^{-3/2} 被忽略,因为它是一个对我来说无关紧要的常数因子,因为我只对概率之间的比率感兴趣)
def compute_probabilities(img, kernels):
np.seterr(divide='ignore') # 1 / covariance logs an error otherwise
result = np.zeros((img.shape[0], img.shape[1]))
for row_pos, row_val in enumerate(img):
for col_pos, val in enumerate(row_val):
prob = 0.0
for kernel in kernels:
mean, covariance, weight = kernel
val_sub_mu = np.array([val]).T - mean
cov_inv = np.where(covariance != 0, 1 / covariance, 0)
tmp = val_sub_mu.T.dot(cov_inv).dot(val_sub_mu)
prob += weight / np.sqrt(np.linalg.norm(covariance)) * \
math.exp(-0.5 * tmp)
result[row_pos][col_pos] = prob
np.seterr(divide='warn')
return result
输入:cv2.imread
在一些 jpg 上,它给出了一个包含 3 个颜色 channel 的 3 uint8 结构的二维数组(高 x 宽)。
内核是一个 namedtuple('Kernel', 'mean covariance weight')
,均值是一个向量,协方差是一个3x3
除对角线以外的所有内容均为零且权重为 float 的矩阵 0 < weight < 1
.为简单起见,我只指定对角线,然后将其转换为 3x3 矩阵:(表示不是一成不变的,我不关心它是如何表示的,所以可以随意更改所有这些):
some_kernels = [
Kernel(np.array([(73.53, 29.94, 17.76)]), np.array([(765.40, 121.44, 112.80)]), 0.0294),
...
]
def fixup_kernels(kernels):
new_kernels = []
for kernel in kernels:
cov = np.zeros((3, 3))
for pos, c in enumerate(kernel.covariance[0]):
cov[pos][pos] = c
new_kernels.append(Kernel(kernel.mean.T, cov, kernel.weight))
return new_kernels
some_kernels = fixup_kernels(some_kernels)
img = cv2.imread("something.jpg")
result = compute_probabalities(img, some_kernels)
最佳答案
编辑
我验证了这会产生与原始代码相同的结果:
def compute_probabilities_fast(img, kernels):
np.seterr(divide='ignore')
result = np.zeros((img.shape[0], img.shape[1]))
for kernel in kernels:
mean, covariance, weight = kernel
cov_inv = np.where(covariance != 0, 1 / covariance, 0)
mean = mean[:,0]
img_sub_mu = img - mean
img_tmp = np.sum( img_sub_mu.dot(cov_inv) * img_sub_mu, axis=2 )
result += (weight / np.sqrt(np.linalg.norm(covariance))) * np.exp(-0.5 * img_tmp)
return result
解释:
mean[:,0]
使形状简单地 (3,) 而不是 (3,1)。
img - mean
广播到整个图像并从每个像素中减去均值。
img_sub_mu.dot(cov_inv)
大致等同于 val_sub_mu.T.dot(cov_inv)
。
np.sum( ... * img_sub_mu, axis=2 )
大致等同于 .dot(val_sub_mu)
。但是不能使用点,因为这样做会增加额外的维度。例如,数组 M x N x K 点缀数组 M x K x N 会产生结果 M x N x M x N,点在一维和多维数据上的表现不同。所以我们只进行逐元素乘法,然后沿最后一个维度求和。
实际上,问题中的“高斯内核总和”让我感到困惑。所要求的是一种计算,其中对于每个输出像素,值仅取决于同一像素的输入值,而不取决于相邻像素的值。因此,这与高斯模糊(将使用卷积)完全不同,它只是对每个像素单独执行的计算。
附言1/covariance
是有问题的。您确定不想用 np.linalg.inv(covariance)
代替吗?
旧答案
听起来您想要的是其中之一:
scipy.ndimage.filters.convolve
这个问题有点令人困惑,你是想计算一堆与不同高斯卷积的图像,还是与高斯总和卷积的单个图像?你的内核是可分离的吗? (如果是,请使用两个卷积 Mx1 和 1xN 而不是一个 MxN)您使用的 scipy 函数在任何情况下都是相同的。
当然,您还希望使用 numpy.random.normal
和 meshgrid
的组合来预先计算您的内核。
关于python - 高效的密度函数计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19968065/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!