Computer vision 三次样条/曲线拟合

Computer vision 三次样条/曲线拟合,computer-vision,curve-fitting,spline,cubic-spline,Computer Vision,Curve Fitting,Spline,Cubic Spline,我需要确定照明变化的参数,这是由连续分段多项式C(t)定义的,其中f(t)是由两个边界点(t1,C)和(t2,0)定义的三次曲线,也就是f’(t1)=0和f’(t2)=0。 强度曲线从阴影边界上的法线采样,如下所示: f(x)= x^3+a2*x^2+a1*x1+a0 - 3 variables 每一行都是样本,显示照度的变化。所以X是列数,Y是像素强度 我有这样的真实数据(从所有样本中抽取一个样本): 我总共有N个样本,我需要确定参数(c,t1,t2) 我怎么做 我试图通过在Mat

我需要确定照明变化的参数,这是由连续分段多项式C(t)定义的,其中f(t)是由两个边界点(t1,C)和(t2,0)定义的三次曲线,也就是f’(t1)=0和f’(t2)=0。

强度曲线从阴影边界上的法线采样,如下所示:

f(x)= x^3+a2*x^2+a1*x1+a0 - 3 variables
每一行都是样本,显示照度的变化。所以X是列数,Y是像素强度

我有这样的真实数据(从所有样本中抽取一个样本):

我总共有N个样本,我需要确定参数(c,t1,t2)

我怎么做

我试图通过在Matlab中求解线性方程来实现:

%defined by hand
t1= 10;
t2= 14;

avr_curve= [41, 40, 40, 41, 41, 42, 42, 43, 43, 43, 51, 76, 98, 104, 104, 103, 104, 105, 105, 107, 105];
x=         [1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14,  15,  16,  17,  18,  19,  20,  21];
%x=        [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; %real x axis

%%%model 1
%%f(x)= x^3+a2*x^2+a1*x1+a0 - 3 variables
%A= zeros(4,3);
%b= [43  104]';
%%cubic equation at t1 
%A(1,1)= t1^2; %a2
%A(1,2)= t1; %a1
%A(1,3)= 1; %a0
%b(1,1)= b(1,1)-t1^3;
%%cubic equation at t2
%A(2,1)= t2^2; %a2
%A(2,2)= t2; %a1
%A(2,3)= 1; %a0
%b(2,1)= b(2,1)-t1^3;
%%1st derivative at t1
%A(3,1)= 2*t1; %a2
%A(3,2)= 1; %a1
%A(3,3)= 0; %a0
%b(3,1)= -3*t1^2;
%%1st derivative at t2
%A(4,1)= 2*t2; %a2
%A(4,2)= 1; %a1
%A(4,3)= 0; %a0
%b(4,1)= -3*t2^2;

%model 2
%f(x)= a3*x^3+a2*x^2+a1*x1+a0 - 4 variables
A= zeros(4,4);
b= [43  104]';
%cubic equation at t1 
A(1,1)= t1^3; %a3
A(1,2)= t1^2; %a2
A(1,3)= t1; %a1
A(1,4)= 1; %a0
b(1,1)= b(1,1);
%cubic equation at t2
A(2,1)= t2^3; %a3
A(2,2)= t2^2; %a2
A(2,3)= t2; %a1
A(2,4)= 1; %a0
b(2,1)= b(2,1);
%1st derivative at t1
A(3,1)= 3*t1^2; %a3
A(3,2)= 2*t1; %a2
A(3,3)= 1; %a1
A(3,4)= 0; %a0
b(3,1)= 0;
%1st derivative at t2
A(4,1)= 3*t2^2; %a3
A(4,2)= 2*t2; %a2
A(4,3)= 1; %a1
A(4,4)= 0; %a0
b(4,1)= 0;

size(A)
size(b)
u= A\b;
u

%estimated cubic curve
%dx=[1:21]; % global view
dx=t1-1:t2+1; % local view in [t1 t2]
for x= dx
  %fx(x)=x^3+u(1)*x^2+u(2)*x+u(3); % model 1
  fx(x)= u(1)*x^3+u(2)*x^2+u(3)*x+u(4); % model 2
end

err= 0;
for x= dx
  err= err+(fx(x)-avr_curve(x))^2;
end

err

figure,plot(dx,avr_curve(dx),dx,fx(dx))
avr_曲线是平均曲线,通过对所有样本进行平均得到

f(x)=x^3+a2*x^2+a1*x1+a0是三次函数

%t1,t2 selected by hand
t1= 10;
t2= 15;

offset=10;
avr_curve= [41, 40, 40, 41, 41, 42, 42, 43, 43, 43, 51, 76, 98, 104, 104, 103, 104, 105, 105, 107, 105];
%gradx= convn(avr_curve,[-1 1],'same');

A= zeros(2*offset+1,3);
%b= zeros(2*offset+1,1);
b= avr_curve';
%for i= 1:2*offset+1
for i=t1:t2
  i
  x= i-offset-1
  A(i,1)=  x^2; %a2
  A(i,2)=  x; %a1
  A(i,3)=  1; %a0 
  b(i,1)= b(i,1)-x^3;
end

u= A\b;

figure,plot(avr_curve(t1:t2))


%estimated cubic curve
for i= 1:2*offset+1 
  x= i-offset-1;
  fx(i)=x^3+u(1)*x^2+u(2)*x+u(3);
end

figure,plot(fx(t1:t2))
[t1 t2]上avr_曲线的一部分

我得到的三次曲线(看起来不像avr_曲线)

那我做错了什么

更新: 似乎我的错误是因为我使用3个变量来建模三次多项式,如下所示:

f(x)= x^3+a2*x^2+a1*x1+a0 - 3 variables
但我使用了4个变量,一切似乎都正常:

f(x)= a3*x^3+a2*x^2+a1*x1+a0 - 4 variables 
以下是Matlab中的代码:

%defined by hand
t1= 10;
t2= 14;

avr_curve= [41, 40, 40, 41, 41, 42, 42, 43, 43, 43, 51, 76, 98, 104, 104, 103, 104, 105, 105, 107, 105];
x=         [1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14,  15,  16,  17,  18,  19,  20,  21];
%x=        [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; %real x axis

%%%model 1
%%f(x)= x^3+a2*x^2+a1*x1+a0 - 3 variables
%A= zeros(4,3);
%b= [43  104]';
%%cubic equation at t1 
%A(1,1)= t1^2; %a2
%A(1,2)= t1; %a1
%A(1,3)= 1; %a0
%b(1,1)= b(1,1)-t1^3;
%%cubic equation at t2
%A(2,1)= t2^2; %a2
%A(2,2)= t2; %a1
%A(2,3)= 1; %a0
%b(2,1)= b(2,1)-t1^3;
%%1st derivative at t1
%A(3,1)= 2*t1; %a2
%A(3,2)= 1; %a1
%A(3,3)= 0; %a0
%b(3,1)= -3*t1^2;
%%1st derivative at t2
%A(4,1)= 2*t2; %a2
%A(4,2)= 1; %a1
%A(4,3)= 0; %a0
%b(4,1)= -3*t2^2;

%model 2
%f(x)= a3*x^3+a2*x^2+a1*x1+a0 - 4 variables
A= zeros(4,4);
b= [43  104]';
%cubic equation at t1 
A(1,1)= t1^3; %a3
A(1,2)= t1^2; %a2
A(1,3)= t1; %a1
A(1,4)= 1; %a0
b(1,1)= b(1,1);
%cubic equation at t2
A(2,1)= t2^3; %a3
A(2,2)= t2^2; %a2
A(2,3)= t2; %a1
A(2,4)= 1; %a0
b(2,1)= b(2,1);
%1st derivative at t1
A(3,1)= 3*t1^2; %a3
A(3,2)= 2*t1; %a2
A(3,3)= 1; %a1
A(3,4)= 0; %a0
b(3,1)= 0;
%1st derivative at t2
A(4,1)= 3*t2^2; %a3
A(4,2)= 2*t2; %a2
A(4,3)= 1; %a1
A(4,4)= 0; %a0
b(4,1)= 0;

size(A)
size(b)
u= A\b;
u

%estimated cubic curve
%dx=[1:21]; % global view
dx=t1-1:t2+1; % local view in [t1 t2]
for x= dx
  %fx(x)=x^3+u(1)*x^2+u(2)*x+u(3); % model 1
  fx(x)= u(1)*x^3+u(2)*x^2+u(3)*x+u(4); % model 2
end

err= 0;
for x= dx
  err= err+(fx(x)-avr_curve(x))^2;
end

err

figure,plot(dx,avr_curve(dx),dx,fx(dx))
区间上的样条曲线[t1-1 t2+1]

而且是全间隔的

免责声明 我无法保证下面给出的代码或方法的正确性,在使用任何代码或方法之前,请务必使用您的批判意识。

0定义问题 你有一个分段定义的函数

其中f(t)是一个三次函数,为了唯一地识别它,给出了以下附加条件

您希望恢复参数t1、t2和sigma的最佳值,以最小化给定点集的误差

这本质上是一种曲线拟合

1参数化f(t)三次函数 为了计算候选Cl(t)函数和我们需要计算f(t)的点集之间的误差,它的一般形式(立方)是

所以我们似乎有四个额外的参数要考虑。实际上,这些参数完全由自由的三个参数t1、t2和sigma定义。
重要的是不要混淆自由参数和从属参数

给定f(t)上的附加条件,我们可以建立这个线性系统

其中有一个解决方案(如预期)由

这告诉我们如何在给定三个自由参数的情况下计算立方体的参数。
这样Cl(t)就完全确定了,现在是时候找到最好的候选者了

2尽量减少误差 我现在通常会选择最小二乘法。
由于这不是一个线性函数,因此没有计算σ、t1和t2的闭合形式。
然而,也有一些数值方法,比如

然而,无论如何,需要计算三个参数的偏导数。
我不知道如何计算像t1这样的分离参数的导数。

我搜索了MathSE,找到了解决同一问题的问题,但没有人回答

没有偏导数,最小二乘法就结束了。

因此,我采取了一种更实际的方法,在C中实现了一个蛮力函数,该函数尝试所有可能的参数三元组并返回最佳匹配

3蛮力函数 考虑到问题的性质,结果证明样本数量为O(n^2)

该算法如下:将样本集分为三部分,第一部分是t1之前的点,第二部分是t1和t2之间的点,最后一部分是t2之后的点

第一部分仅用于计算sigma,sigma只是第1部分中各点的算术平均值

t1和t2通过一个循环进行计算,t1被设置为原始点集中的每个可能点,从第二个点开始向前。
对于t1的每个选择,t2设置为t1之后的每个可能点

在每次迭代中,都会计算一个错误,如果它是所见过的最小值,则会保存使用的参数

由于绝对值应该是快的(肯定比平方快),并且它符合度量的目的,因此误差可以用计算机表示为残差的绝对值

4.守则
#包括
#包括
曲线上的浮点点(浮点西格玛、浮点t1、浮点t2、浮点t)
{
浮子a、b、c、d、K;
如果(t=t2)
返回0;
K=(t1-t2)*(t1-t2)*(t1-t2);
a=-2*sigma/K;
b=3*sigma*(t1+t2)/K;
c=-6*西格玛*t1*t2/K;
d=σ*t2*t2*(3*t1-t2)/K;
返回a*t*t*t+b*t*t+c*t+d;
}
浮点计算错误(浮点西格玛、浮点t1、浮点t2、整数s、整数dx、整数*数据、整数len)
{
浮动误差=0;
无符号整数i;
对于(i=0;i/*计算sigma作为点的平均值这是一个应用数学问题,不是真正的编程问题。我投票决定结束。你应该和数学交换一样。在结束选项中,我看到的最接近的东西是@CarlosBribbiescas不这样认为,关于样条线的问题很多。首先,beca