为什么我的2D高斯拟合度这么差?

时间:2018-08-12 23:34:20

标签: python numpy scipy gaussian data-fitting

我正在使用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()

Here is my randomly generated example data

# 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()

And here is my result (for this set of example data).

由于每次运行此代码时数据都会自行重新生成,所以我注意到有时它确实可以准确拟合,但效果并不理想。为什么这么不可靠?

此外,假设我确实得到了正确的拟合,如何绘制绘制的居中2D高斯图像(而不只是原始图像上的标记)?

0 个答案:

没有答案