我正在使用Python将2D高斯拟合为2D numpy数组(图像数据)。我的真实数据比较复杂,但是今天(不同的计算机)我无法访问它,因此我制作了一些示例数据。像我的真实数据一样,在中心附近有一个噪声和一个强度更高的像素的对象(这是我要适合的对象)。有时在图像的其他地方也有强度更高的对象,但是我想忽略它们-我只对最靠近几何中心的对象感兴趣,因此我告诉高斯拟合代码在窗口中“猜测”中央。但是,我经常身体不适。有时“ x”位于另一个(较亮的)对象上,有时甚至不在我的主数组中,所以我不确定为什么会这样。下面是我的代码。
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
from matplotlib.patches import Circle
# Generate example data
data = np.random.random((50, 51))
data[1:11, 2:8] = 2.8
data[20:32, 20:30] = 2.1
plt.imshow(data, cmap='gray')
plt.colorbar()
plt.show()
# 2D Gaussian model
def func(xy, x0, y0, sigma, amp):
x, y = xy
A = 1 / (2 * sigma**2)
I = amp * np.exp(-A * ( (x - x0)**2 + (y - y0)**2))
return I
# Generate 2D gaussian
def generate(x0, y0, sigma, H):
x = np.arange(0, max(x0, y0) * 2 + sigma, 1)
y = np.arange(0, max(x0, y0) * 2 + sigma, 1)
xx, yy = np.meshgrid(x, y)
I = func((xx, yy), x0, y0, sigma, amp)
return xx, yy, I
# Fit it to data
def fit(image):
# Prepare fitting -- grid to plot over
x = np.arange(0, np.shape(image)[1], 1)
y = np.arange(0, np.shape(image)[0], 1)
xx, yy = np.meshgrid(x, y)
# Guess intial parameters
x0 = np.shape(image)[1]//2
y0 = np.shape(image)[0]//2
sigma = np.std(image)
amp = image[y0][x0] # Value around middle of image
guesses = [x0, y0, sigma, amp]
pred_params, uncert_cov = optimize.curve_fit(func, (xx.ravel(), yy.ravel()), image.ravel(),
p0=guesses)
# Get residual
predictions = func((xx, yy), *pred_params)
rms = np.sqrt(np.mean((image.ravel() - predictions.ravel())**2))
print("Predicted params : ", pred_params)
print("Residual : ", rms)
return pred_params
def plot(image, params):
fig, ax = plt.subplots()
ax.imshow(image, cmap='gray', interpolation='nearest', origin='lower')
ax.scatter(params[0], params[1], c="red", marker="x")
circle = Circle((params[0], params[1]), params[2], facecolor='none',
edgecolor="red", linewidth=1)
ax.add_patch(circle)
return
params = fit(data)
plot(data, params)
plt.show()
由于每次运行此代码时数据都会自行重新生成,所以我注意到有时它确实可以准确拟合,但效果并不理想。为什么这么不可靠?
此外,假设我确实得到了正确的拟合,如何绘制绘制的居中2D高斯图像(而不只是原始图像上的标记)?