Fitting data from file
显示 更早的评论
Hello,
I am trying to fit data from a file. For that I have created data with simply a sine wave function. Here is my code:
load test_fit
Error using load
Unable to find file or directory 'test_fit.txt'.
Unable to find file or directory 'test_fit.txt'.
x = test_fit(:,1);
y = test_fit(:,2);
fo=fit(y,x,'a*sin(b*x+c)+d');
plot(fo,y,x)
But the results I got are clearly not good:

I'm just wondering if I should specify somwhere the number of itterations or the fitting constrains?
Thank you in advance for any help or comments!
采纳的回答
You can specify those parameters, but what is much more effective is providing good initial guesses (and not mixing up x and y):
test_fit=load(websave('test_fit.txt','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1137860/test_fit.txt'));
x = test_fit(:,1);
y = test_fit(:,2);
plot(x,y,'*')
fo=fit(x,y,'a*sin(b*x+c)+d','StartPoint',[1 4 0 2])
fo =
General model:
fo(x) = a*sin(b*x+c)+d
Coefficients (with 95% confidence bounds):
a = 1 (1, 1)
b = 4 (4, 4)
c = 0.3927 (0.3927, 0.3927)
d = 2 (2, 2)
hold on,plot(fo)

10 个评论
Hi Rik,
Thank you that is really helpful. I have one more question I would like to combine the fitting with the reading data from a an image, but getting an error. Maybe you can help me to solve it?
That is my code:
I=imread('testf5.png');
x = [size(I,2)/2 size(I,2)/2];
y = [0 size(I,1)];
c = improfile(I,x,y);
figure
subplot(2,1,1)
imshow(I)
hold on
plot(x,y,'r')
subplot(2,1,2)
plot(c(:,1,1),'r')
fo=fit(x,y,'m*sin(n*x+o)+p','StartPoint',[125 100 0 125])
but it doesnt like the y column format (I got this error mesage: Y must be a column vector)
If the fit function requires column vectors, why don't you transpose x and y to be column vectors?
But there is a fundamental problem here: you have 2 points, to which you are fitting an equation with 4 unknowns. That is not going to be a reliable fit. It seems like you want to use the profile as your data, but you don't.
Okay I transformed to column vector with:
fo=fit(x(:),y(:),'m*sin(n*x+o)+p','StartPoint',[125 100 0 125])
and also got the error about insuficient point number which I don't understand becaouse there are many points:

Where exactly are you telling the fit function that you want to use all those points? (Hint: you don't)
This I don't fully understand, do I need to then read the data from the graph? I started to use Matlab only recently
You provide x and y as input arguments to the fit function, but that only contains the coordinates of the line you're using for improfile, not the data you're plotting. You probably want to use fit(x_adapted,c,___). That first variable should contain the x position for each value in c. Currently when you're plotting your data, you are implicitly using the index as the x-value. That's fine for getting a first impression of your data, but not for actual analysis.
You probably want this:
x_adapted = linspace(y(1),y(2),numel(c));
I would also suggest doing a basic Matlab tutorial. The Onramp tutorial is provided for free by Mathworks.
Okay, thank you now that is clear but still got an error with fit weights. Even if I define wieghts I still get it
Error using fit>iFit
X, Y and WEIGHTS cannot have NaN values.
Error in fit (line 116)
[fitobj, goodness, output, convmsg] = iFit( xdatain, ydatain, fittypeobj, ...
Error in testfitimage (line 20)
fo=fit(transpose(x_adapted),c(:,1,1),ft)
websave('testf5.png','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1139785/testf5.png');
I=imread('testf5.png');
x = [size(I,2)/2 size(I,2)/2];
y = [0 size(I,1)];
c = improfile(I,x,y);
figure
subplot(2,1,1)
imshow(I)
hold on
plot(x,y,'-o')
subplot(2,1,2)
plot(c(:,1,1),'-o')
x_adapted = linspace(y(1),y(2),numel(c(:,1,1)));
ft = fittype('m*sin(n*x+o)+p');
options=fitoptions(ft);
options.StartPoint = [125 100 0 125];
options.Weights = [1,1];
plot(x_adapted(:),c(:,1,1))

fo=fit(transpose(x_adapted),c(:,1,1),ft)
Error using fit>iFit
X, Y and WEIGHTS cannot have NaN values.
X, Y and WEIGHTS cannot have NaN values.
Error in fit (line 116)
[fitobj, goodness, output, convmsg] = iFit( xdatain, ydatain, fittypeobj, ...
x = [size(I,2)/2 size(I,2)/2];
y = [0 size(I,1)];
c = improfile(I,x,y);
y = 0 is outside the image coordinates, so the profile gives NaN at that location.
If you look at the code below, you see that c starts with a NaN. So we should remove it.
I = imread(websave('testf5.png','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1139785/testf5.png'));
x = [size(I,2)/2 size(I,2)/2];
y = [0 size(I,1)];
c = improfile(I,x,y);
c = c(:,1,1); % select red chanel
x_adapted = linspace(y(1),y(2),numel(c));
x_adapted = x_adapted.'; % transpose 1x1491 to 1491x1
subplot(2,1,1)
imshow(I)
hold on
plot(x,y,'-o')
hold off
subplot(2,1,2)
plot(x_adapted,c)

ft = fittype('m*sin(n*x+o)+p');
options=fitoptions(ft);
options.StartPoint = [125 100 0 125];
options.Weights = [1,1];
find(isnan(x_adapted)),find(isnan(c))
ans =
0×1 empty double column vector
ans = 1
Here is the problem, so we'll have to remove that point.
L = isnan(x_adapted) | isnan(c); % the first part is just good habit
x_adapted(L) = [];
c(L) = [];
% Now we can safely to the fit:
fo=fit(x_adapted,c,ft,StartPoint=[125 100 0 125])
fo =
General model:
fo(x) = m*sin(n*x+o)+p
Coefficients (with 95% confidence bounds):
m = 0.15 (-6.376, 6.676)
n = 100 (99.9, 100.1)
o = -0.001634 (-87.15, 87.15)
p = 129.3 (124.6, 133.9)
figure,plot(fo)

So the fit is not great, you will have to adjust the start point.
If my answer helped you, please consider marking it as accepted answer.
更多回答(0 个)
类别
在 帮助中心 和 File Exchange 中查找有关 Hough Transform 的更多信息
另请参阅
选择网站
选择网站以获取翻译的可用内容,以及查看当地活动和优惠。根据您的位置,我们建议您选择:。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
