Я пытаюсь подобрать несколько гауссиан из трехмерного графика и либо исключить их из наших данных, либо получить значения x, y положения гауссиан.
Это пока что код:
import numpy as np
import cv2
import math
import matplotlib. pyplot as plt
из mpl_toolkits import mplot3d
import mpl_toolkits.mplot3d
from mpl_toolkits.mplot3d import Axes3D
from scipy.optimize import curve19 *
из scipy.optimize import минимизировать
Импортировать изображение, установить как тип с плавающей запятой и преобразовать в оттенки серого
source = cv2.imread ('single_star1.jpg', 1)
img = source.astype (np.float32)
gray = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY)
Конвертировать изображение в numpy массив
n = np.array (серый)
cols = n.mean (axis = 0) # слева направо
rows = n.mean (axis = 1) # снизу вверх
nx = len (cols)
Преобразование многомерного массива n в трехмерный массив
real_array = []
для x в диапазоне (0, len (n [0 ,:]), 5):
for y in range(0, len(n[:,0]), 5):
array = (x, y, n[y,x])
real_array.append(array)
real_array = np.array (real_ array)
flat_array = n.flatten ()
print (flat_array)
Построить график
plt.rcParams ["figure.figsize"] = 9.6, 12.8
ax = plt.axes (projection = '3d')
ax.plot_trisurf (real_array [:, 0], real_array [:, 1], real_array [:, 2 ], cmap = 'jet', edgecolor = 'none') # Int3d
ax.set_xlabel ('x-axis')
ax.set_ylabel ('y-axis')
ax.invert_yaxis ()
ax.set_zlabel ('Intensity')
def twoD_Gaussian_fake (x, y, амплитуда, xo, yo, sigma_x, sigma_y, theta, смещение) :
# x, y = xy
xo = float(xo)
yo = float(yo)
a = (np.cos(theta)**2)/(2*sigma_x**2) + (np.sin(theta)**2)/(2*sigma_y**2)
b = -(np.sin(2*theta))/(4*sigma_x**2) + (np.sin(2*theta))/(4*sigma_y**2)
c = (np.sin(theta)**2)/(2*sigma_x**2) + (np.cos(theta)**2)/(2*sigma_y**2)
g = offset + amplitude*np.exp( - (a*((x-xo)**2) + 2*b*(x-xo)*(y-yo) + c*((y-yo)**2)))
return g.ravel()
def twoD_Gaussian_optimizable (xy, амплитуда, xo, yo, sigma_x, sigma_y, theta, offset):
ii = []
jj = []
for k in range(len(xy)):
j = xy[math.ceil(k/(nx))]
i = xy[k % (nx)]
ii.append(i)
jj.append(j)
xo = float(xo)
yo = float(yo)
iii = np.array(ii)
jjj = np.array(jj)
a = (np.cos(theta)**2)/(2*sigma_x**2) + (np.sin(theta)**2)/(2*sigma_y**2)
b = -(np.sin(2*theta))/(4*sigma_x**2) + (np.sin(2*theta))/(4*sigma_y**2)
c = (np.sin(theta)**2)/(2*sigma_x**2) + (np.cos(theta)**2)/(2*sigma_y**2)
g = offset + amplitude*np.exp( - (a*((iii-xo)**2) + 2*b*(iii-xo)*(jjj-yo) + c*((jjj-yo)**2)))
return g.ravel()
Создание поддельных данных
x = real_array [:, 0]
y = real_array [:, 1]
fake_gauss = twoD_Gaussian_fake (x, y, 200, 300, 400, 100, 50, np.pi / 4, 15)
data_noisy = fake_gauss + 5 * np.random.normal (size = len (x))
# Построить график
plt.rcParams ["figure.figsize "] = 9,6, 12,8
* 1 089 * ax = plt.axes (projection = '3d')
ax.plot_trisurf (x, y, data_noisy, cmap = 'jet', edgecolor = 'none') # Int3d
ax.set_xlabel ('ось x')
ax.set_ylabel ('ось y')
ax.invert_yaxis ()
ax.set_zlabel ('Intensity' )
initial_guess = (3,100,100,20,40,0,10)
popt, pcov = curve_fit (twoD_Gaussian_optimizable, flat_array, data_noisy, p0 = initial_guess)
plt. rcParams ["figure.figsize"] = 9.6, 12.8
ax = plt.axes (projection = '3d')
ax.plot_trisurf (x, y, twoD_Gaussian_fake (x, y, popt), cmap = 'jet', edgecolor = 'none') # Int3d
ax.set_xlabel ('x-axis')
ax.set_ylabel ('y-axis')
ax.invert_yaxis ()
ax.set_zlabel ('Интенсивность')