Как я могу сделать свой 2D гауссовской, чтобы соответствовать моему изображению - PullRequest
0 голосов
/ 28 мая 2018

Я пытаюсь подогнать 2D гауссов к изображению, чтобы найти местоположение самой яркой точки на нем.Мой код выглядит следующим образом:

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 везде, где есть x0 и y0.Значения пикселей на моем изображении очень малы.Максимальное значение - 0,0007, стандартное отклонение - 0,0001, а x и y на несколько порядков больше.Поэтому я полагаю, что моя проблема в том, что из-за этого мой эквалайзер везде стремится к нулю, поэтому curve_fit не работает.Мне интересно, есть ли лучший способ построить мой гауссиан, чтобы он правильно строил?

1 Ответ

0 голосов
/ 28 мая 2018

У меня нет доступа к вашему изображению.Вместо этого я сгенерировал некоторое тестовое «изображение» следующим образом:

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

Кроме того, я изменил ваш код для построения графиков, чтобы увеличить радиус круга на 10:

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

иЯ закомментировал еще две строки:

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

Результат, который я получаю, показан на прилагаемом изображении, и он выглядит для меня разумным:

enter image description here

Может быть, проблема в том, как вы получаете доступ к данным из файла FITS?(например, image = image[0,0,:,:]) Является ли массив данных 4D?Почему у вас 4 индекса?

Я также видел, что вы задали аналогичный вопрос здесь: Astropy.model 2DGaussian выпуск , в котором вы пытались использовать только astropy.modeling.Я рассмотрю этот вопрос.


ПРИМЕЧАНИЕ: вы можете заменить код, такой как

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...