本文介绍了如何使我的 2D 高斯适合我的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将2D高斯拟合到图像中,以找到图像中最亮点的位置.我的代码如下:

I am trying to fit a 2D Gaussian to an image to find the location of the brightest point in it. My code looks like this:

import numpy as np
import astropy.io.fits as fits
import os
from astropy.stats import mad_std
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from lmfit.models import GaussianModel
from astropy.modeling import models, fitting

def gaussian(xycoor,x0, y0, sigma, amp):
    '''This Function is the Gaussian Function'''

    x, y = xycoor # x and y taken from fit function.  Stars at 0, increases by 1, goes to length of axis
    A = 1 / (2*sigma**2)
    eq =  amp*np.exp(-A*((x-x0)**2 + (y-y0)**2)) #Gaussian
    return eq


def fit(image):
    med = np.median(image)
    image = image-med
    image = image[0,0,:,:]

    max_index = np.where(image >= np.max(image))
    x0 = max_index[1] #Middle of X axis
    y0 = max_index[0] #Middle of Y axis
    x = np.arange(0, image.shape[1], 1) #Stars at 0, increases by 1, goes to length of axis
    y = np.arange(0, image.shape[0], 1) #Stars at 0, increases by 1, goes to length of axis
    xx, yy = np.meshgrid(x, y) #creates a grid to plot the function over
    sigma = np.std(image) #The standard dev given in the Gaussian
    amp = np.max(image) #amplitude
    guess = [x0, y0, sigma, amp] #The initial guess for the gaussian fitting

    low = [0,0,0,0] #start of data array
    #Upper Bounds x0: length of x axis, y0: length of y axis, st dev: max value in image, amplitude: 2x the max value
    upper = [image.shape[0], image.shape[1], np.max(image), np.max(image)*2]
    bounds = [low, upper]

    params, pcov = curve_fit(gaussian, (xx.ravel(), yy.ravel()), image.ravel(),p0 = guess, bounds = bounds) #optimal fit.  Not sure what pcov is.

    return params


def plotting(image, params):
    fig, ax = plt.subplots()
    ax.imshow(image)
    ax.scatter(params[0], params[1],s = 10, c = 'red', marker = 'x')
    circle = Circle((params[0], params[1]), params[2], facecolor = 'none', edgecolor = 'red', linewidth = 1)

    ax.add_patch(circle)
    plt.show()

data = fits.getdata('AzTECC100.fits') #read in file
med = np.median(data)
data = data - med

data = data[0,0,:,:]

parameters = fit(data)

#generates a gaussian based on the parameters given
plotting(data, parameters)

图像正在绘制并且代码没有给出错误,但拟合不起作用.它只是将 x 放在 x0y0 所在的位置.我图像中的像素值很小.最大值为 0.0007,std dev 为 0.0001,xy 大几个数量级.所以我相信我的问题是因为这个我的 eq 在任何地方都会变为零,所以 curve_fit 失败了.我想知道是否有更好的方法来构造我的高斯,以便正确绘制?

The image is plotting and the code is giving no errors but the fitting isn't working. It's just putting an x wherever the x0 and y0 are. The pixel values in my image are very small. The max value is 0.0007 and std dev is 0.0001 and the x and y are a few orders of magnitude larger. So I believe my problem is that because of this my eq is going to zero everywhere so the curve_fit is failing. I'm wondering if there's a better way to construct my gaussian so that it plots correctly?

推荐答案

我无权访问您的图片.相反,我生成了一些测试图像",如下所示:

I do not have access to your image. Instead I have generated some test "image" as follows:

y, x = np.indices((51,51))
x -= 25
y -= 25
data = 3 * np.exp(-0.7 * ((x+2)**2 + (y-1)**2))

此外,我还修改了用于绘制的代码,以将圆的半径增加10:

Also, I have modified your code for plotting to increase the radius of the circle by 10:

circle = Circle((params[0], params[1]), 10 * params[2], ...)

我又注释掉了两行:

# image = image[0,0,:,:]
# data = data[0,0,:,:]

我得到的结果显示在附图中,对我来说看起来很合理:

The result that I get is shown in the attached image and it looks reasonable to me:

问题是否在于您如何从 FITS 文件访问数据?(例如, image = image [0,0,:,:] )数据是4D数组吗?为什么有4个索引?

Could it be that the issue is in how you access data from the FITS file? (e.g., image = image[0,0,:,:]) Are the data 4D array? Why do you have 4 indices?

我还看到您在这里提出了类似的问题: Astropy.model 2DGaussian问题,您尝试仅使用 astropy.modeling .我将调查这个问题.

I also saw that you have asked a similar question here: Astropy.model 2DGaussian issue in which you tried to use just astropy.modeling. I will look into that question.

注意:您可以替换代码,例如

NOTE: you can replace code such as

max_index = np.where(image >= np.max(image))
x0 = max_index[1] #Middle of X axis
y0 = max_index[0] #Middle of Y axis

使用

y0, x0 = np.unravel_index(np.argmax(data), data.shape)

这篇关于如何使我的 2D 高斯适合我的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 05:34