- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个标准的高斯函数,看起来像这样:
def gauss_fnc(x, amp, cen, sigma):
return amp * np.exp(-(x - cen) ** 2 / (2 * sigma ** 2))
我有一个 fit_gaussian 函数,它使用 scipy 的 curve_fit 来拟合我的 gauss_fnc:
from scipy.optimize import curve_fit
def fit_gaussian(x, y):
mean = sum(x * y) / sum(y)
sigma = np.sqrt(sum(y * (x - mean) ** 2) / sum(y))
opt, cov = curve_fit(gauss_fnc, x, y, p0=[max(y), mean, sigma])
values = gauss_fnc(x, *opt)
return values, sigma, opt, cov
如果数据类似于正常的高斯函数,我可以确认这很好用,请参见示例:
但是,如果信号太尖或太窄,它将无法按预期工作。峰值高斯示例:
这是一个平顶或超高斯的例子:
目前,由于高斯切割边缘,高斯变得越平坦,丢失的信息就越多。我怎样才能改进函数或曲线拟合,以便能够像这张图片一样拟合峰值和平顶信号:
编辑:
我提供了一个最小的工作示例来进行尝试:
from PyQt5.QtWidgets import (QApplication, QMainWindow)
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from scipy.optimize import curve_fit
import numpy as np
from PyQt5.QtWidgets import QWidget, QGridLayout
def gauss_fnc(x, amp, cen, sigma):
return amp * np.exp(-(x - cen) ** 2 / (2 * sigma ** 2))
def fit_gauss(x, y):
mean = sum(x * y) / sum(y)
sigma = np.sqrt(sum(y * (x - mean) ** 2) / sum(y))
opt, cov = curve_fit(gauss_fnc, x, y, p0=[max(y), mean, sigma])
vals = gauss_fnc(x, *opt)
return vals, sigma, opt, cov
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.results = list()
self.setWindowTitle('Gauss fitting')
self.setGeometry(50, 50, 1280, 1024)
self.setupLayout()
self.raw_data1 = np.array([1, 1, 1, 1, 3, 5, 7, 8, 9, 10, 11, 10, 9, 8, 7, 5, 3, 1, 1, 1, 1], dtype=int)
self.raw_data2 = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 200, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=int)
self.raw_data3 = np.array([1, 1, 1, 1, 1, 3, 5, 9, 10, 10, 10, 10, 10, 9, 5, 3, 1, 1, 1, 1, 1], dtype=int)
self.plot()
def setupLayout(self):
# Create figures
self.fig1 = FigureCanvas(Figure(figsize=(5, 4), dpi=100))
self.fig1AX = self.fig1.figure.add_subplot(111, frameon=False)
self.fig1AX.get_xaxis().set_visible(True)
self.fig1AX.get_yaxis().set_visible(True)
self.fig1AX.yaxis.tick_right()
self.fig1AX.yaxis.set_label_position("right")
self.fig2 = FigureCanvas(Figure(figsize=(5, 4), dpi=100))
self.fig2AX = self.fig2.figure.add_subplot(111, frameon=False)
self.fig2AX.get_xaxis().set_visible(True)
self.fig2AX.get_yaxis().set_visible(True)
self.fig2AX.yaxis.tick_right()
self.fig2AX.yaxis.set_label_position("right")
self.fig3 = FigureCanvas(Figure(figsize=(5, 4), dpi=100))
self.fig3AX = self.fig3.figure.add_subplot(111, frameon=False)
self.fig3AX.get_xaxis().set_visible(True)
self.fig3AX.get_yaxis().set_visible(True)
self.fig3AX.yaxis.tick_right()
self.fig3AX.yaxis.set_label_position("right")
self.widget = QWidget(self)
grid = QGridLayout()
grid.addWidget(self.fig1, 0, 0, 1, 1)
grid.addWidget(self.fig2, 1, 0, 1, 1)
grid.addWidget(self.fig3, 2, 0, 1, 1)
self.widget.setLayout(grid)
self.setCentralWidget(self.widget)
def plot(self):
x = len(self.raw_data1)
xvals, sigma, optw, covar = fit_gauss(range(x), self.raw_data1)
self.fig1AX.clear()
self.fig1AX.plot(range(len(self.raw_data1)), self.raw_data1, 'k-')
self.fig1AX.plot(range(len(self.raw_data1)), xvals, 'b-', linewidth=2)
self.fig1AX.margins(0, 0)
self.fig1.figure.tight_layout()
self.fig1.draw()
xvals, sigma, optw, covar = fit_gauss(range(x), self.raw_data1)
self.fig2AX.clear()
self.fig2AX.plot(range(len(self.raw_data2)), self.raw_data2, 'k-')
self.fig2AX.plot(range(len(self.raw_data2)), xvals, 'b-', linewidth=2)
self.fig2AX.margins(0, 0)
self.fig2.figure.tight_layout()
self.fig2.draw()
self.fig3AX.clear()
self.fig3AX.plot(range(len(self.raw_data3)), self.raw_data3, 'k-')
self.fig3AX.plot(range(len(self.raw_data3)), xvals, 'b-', linewidth=2)
self.fig3AX.margins(0, 0)
self.fig3.figure.tight_layout()
self.fig3.draw()
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
最后一张图来自here .
最佳答案
您可以使用高斯定义函数进行曲线拟合:
import numpy as np
from matplotlib import pyplot as plt
from scipy.optimize import curve_fit
x = range(21)
y_peak = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 200, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=int)
y_flat_top = np.array([1, 1, 1, 1, 1, 3, 5, 9, 10, 10, 10, 10, 10, 9, 5, 3, 1, 1, 1, 1, 1], dtype=int)
# define gauss function
def Gauss(x, a, x0, sigma):
return a * np.exp(-(x - x0)**2 / (2 * sigma**2))
# fit function
popt, pcov = curve_fit(Gauss, x, y_peak)
# set data for curve plot
x_fit = np.linspace(0,21,1000)
y_fit = Gauss(x_fit, popt[0], popt[1], popt[2])
y_fit = Gauss(x_fit, max(y_flat_top) , popt[1], popt[2])
# plot data
fig, ax = plt.subplots()
plt.plot(x, y_peak, '.')
plt.plot(x_fit, y_fit, '-', label='peak')
plt.legend()
plt.show()
输出:
使用广义正态分布:很难适应。您可以尝试使用边界并尝试为函数添加一些额外的参数以获得更好的拟合度。另一种选择是使用 differential evolution algorithm找到最合适的。
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
# set data
x = np.linspace(-4, 4, 20)
y_peak = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 200, 2, 1, 1, 1, 1, 1, 1, 1, 1], dtype=int)
y_flat_top = np.array([1, 1, 1, 1, 1, 3, 5, 9, 10, 10, 10, 10, 10, 9, 5, 3, 1, 1, 1, 1], dtype=int)
y = y_peak
# define generalized normal distribution
def general_norm(x, gamma, beta):
value = (beta/(2*gamma*(1/beta)))*np.exp(-np.abs(x)**beta)
return value
# set bounds
bounds_peak = ((0,0),(100,9))
bounds_flat_top = ((0,7),(100,9))
# fit function
popt, pcov = curve_fit(general_norm, x, y, bounds=bounds_peak)
# calculate rms
rms = sum((y - general_norm(x, popt[0], popt[1]))**2)
# set data for curve plot
x_fit = np.linspace(-4,4,1000)
y_fit = general_norm(x_fit, popt[0], popt[1])
# plot data
fig, ax = plt.subplots(1, 1)
ax.plot(x, y, '.')
ax.plot(x_fit, y_fit, 'b-')
plt.show()
输出:
关于具有峰值和平顶(超)高斯信号的 Python 曲线拟合问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60316814/
编写求解线性代数方程组的高斯-乔丹方法的任务是我选择用来推进学习 J 的一项练习。系统为 Ax=b,其中 A 是 n-by-n 矩阵,b 和未知的 x 是 n-向量。首先,我从带有控制结构的最简单形式
祝大家新年快乐! :) 我正在 Matlab 中编写 Gauss-Seidel 函数,但遇到了一些问题。 当精度达到 6 位小数时,迭代必须停止。这意味着x-xprevious的无限范数(要求使用它)
我正在尝试使用 scipy 和曲线拟合对我的数据进行高斯拟合,这是我的代码: import csv import numpy as np import matplotlib.pyplot as plt
[已解决,谢谢] 我在 C++ 中开发了下面的代码来使用高斯-塞德尔方法求解线性方程,但我似乎在填充数组时在运行时遇到了一个我无法弄清楚的问题。这是我的代码... #include int main(
我必须设计一种算法作为正向消元法的扩展,在矩阵上进行高斯约旦消元法。我的程序正在执行并创建数字的对角线,但它们并不都是 1。它也不会访问第一行和第一列以将它们更改为 0。最后一列,也就是答案所在的那一
我已经按照 Nixon Aguado 的算法实现了一个高斯滤波器。算法(找到此处描述的模板后 gaussian template )如下。 我相信伪代码是 MATLAB 风格的。 function c
在平滑图像时,我应该应用高斯和双边滤波器等哪种颜色空间版本(灰度、RGB、HSV 等)以获得最佳的去噪效果?是有一个总体趋势,还是在不同情况下会发生变化? 此外,您建议在图像处理中使用什么滤镜和色彩空
我需要根据 Java 中的正态分布对网格(MXN 矩阵)的单元格进行采样。 我知道the Apache Math library具有对一维(1D)值进行采样的函数,因此对于 vector 来说很好,但
我可以使用 random.gauss(mu, sigma) 函数生成高斯数据,但是如何生成二维高斯数据?有这样的功能吗? 最佳答案 如果你可以使用numpy,有numpy.random.multiva
为什么要使用滤波 消除图像中的噪声成分叫作图像的平滑化或滤波操作。信号或图像的能量大部分集中在幅度谱的低频和中频段是很常见的,而在较高频段,感兴趣的信息经常被噪声淹没。因此一个能降低高频成分幅度的
我正在执行高斯混合模型分类,并基于此,在 MATLAB 中使用“mvnpdf”函数。 据我所知,该函数返回传递给它的数据点或元素的多变量概率密度。 但是我试图在 C 上重新创建它,并且我假设 mvnp
I am using rbf,Support Vector machine for large training set=1135x9 matrix and test set{95x9}. I am
我现在多次偶然发现使用 scipy.curve_fit 在 python 中进行拟合比使用其他工具(例如根 ( https://root.cern.ch/ ) 例如,在拟合高斯分布时,使用 scipy
我想在 MATLAB 中绘制高斯波函数的二维表示。我希望 2D 图为一种颜色(绿色),远离高斯中心变得透明。 当我使用 imagesc 时(就像在下一个代码中一样),我在黑色方 block 上得到了一
如果我有数据(每日股票图表是一个很好的例子,但它可以是任何东西),其中我只知道 X 单位销售的范围(高 - 低)但我不知道确切的价格出售的任何给定元素。为简单起见,假设价格范围包含足够的桶(例如,40
这个问题在这里已经有了答案: Impulse, gaussian and salt and pepper noise with OpenCV (10 个回答) 关闭6年前。 我想知道 Python 中
我是一名优秀的程序员,十分优秀!