我有一个合适的问题,我正在尝试使用MATLAB的lsqnonlin
函数解决它并且它的工作非常糟糕。特别是,如果我给它实际解决方案作为起点,求解器继续从那里移开(尽管拟合函数返回该输入的所有零的向量)并产生可怕的东西。我的代码在下面,但它有点长,所以我为此道歉,但我不确定这种特殊情况究竟是什么造成了这种行为,就像在其他情况下那样。
fitting_demo.m:
% Parameters for image
imagemat = zeros(32, 32);
x_centre = 5; y_centre = -10; radius = 3; psf_sigma = 1; height = 1;
% Generate image to fit
actual_image = image_sphere_thin(x_centre, y_centre, radius, psf_sigma, height, imagemat);
figure
% Plot actual image
subplot(2, 1, 1)
imagesc(actual_image)
axis equal
title('Actual image')
% Set up fitting function
x0 = [x_centre, y_centre, radius, psf_sigma, height]; % The solver starts from the solution!
f = @(x)fit_image_sphere_thin(x, imagemat);
% Fit
options = optimoptions(@lsqnonlin, 'Display', 'iter');
[fit, resnorm, residual, exitflag, output] = lsqnonlin(f, x0, [], [], options);
% Display image generated using fitted parameters
subplot(2, 1, 2)
imagesc(image_sphere_thin(fit(1), fit(2), fit(3), fit(4), fit(5), imagemat))
axis equal
title('Fitted image')
fit_image_sphere_thin.m:
function deltas = fit_image_sphere_thin(x0, actual_image)
x_centre = x0(1);
y_centre = x0(2);
radius = x0(3);
% psf_sigma = x0(4); % Commented out to stop crazy things
psf_sigma = 1;
% height = x0(5); % Commented out to stop crazy things
height = 1;
imagemat = zeros(size(actual_image));
sim_image = image_sphere_thin(x_centre, y_centre, radius, psf_sigma, height, imagemat);
sim_vector = sim_image(:);
actual_vector = actual_image(:);
deltas = actual_vector - sim_vector;
end
image_sphere_thin.m:
function I = image_sphere_thin(x_centre, y_centre, radius, psf_sigma, height, imagemat)
image_width = size(imagemat, 2);
image_height = size(imagemat, 1);
image_centre_x = image_width / 2;
image_centre_y = image_height / 2;
x = (1:image_width) - image_centre_x;
y = -(1:image_height) + image_centre_y;
[x, y] = meshgrid(x, y);
X = [x(:) y(:)];
image_vector = cross_section_sphere_thin(x_centre, y_centre, radius, psf_sigma, height, X);
imagemat = reshape(image_vector, size(imagemat));
I = imagemat;
end
cross_section_sphere_thin.m:
function I = cross_section_sphere_thin(x_centre, y_centre, radius, psf_sigma, height, X)
r = sqrt((X(:, 1) - x_centre).^2 + (X(:, 2) - y_centre).^2);
psf_variance = psf_sigma^2;
I = height * (exp(-(r - radius).^2 / (2 * psf_sigma)) - exp(-(r + radius).^2 / (2 * psf_sigma))) ./ r;
I(r == 0) = (2 * radius * height / psf_variance) * exp(-(radius^2) / (2 * psf_variance));
end