Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用样条线勾勒手的轮廓(Matlab)_Matlab_Interpolation_Spline - Fatal编程技术网

用样条线勾勒手的轮廓(Matlab)

用样条线勾勒手的轮廓(Matlab),matlab,interpolation,spline,Matlab,Interpolation,Spline,我正试图编写一个脚本,这样人们就可以把他的手放在屏幕上,用ginput点击几个点,然后让matlab使用样条曲线生成人手的轮廓。但是,我很不确定如何让样条曲线连接单击产生的点,因为它们当然是通过某种参数化来描述的。当点不应该“从左到右”连接时,如何使用matlab中内置的样条线命令 到目前为止,我的代码并不多,它只是一个框,让你点击一些点 FigHandle = figure('Position', [15,15, 1500, 1500]); rectangle('Position',[0,0,

我正试图编写一个脚本,这样人们就可以把他的手放在屏幕上,用ginput点击几个点,然后让matlab使用样条曲线生成人手的轮廓。但是,我很不确定如何让样条曲线连接单击产生的点,因为它们当然是通过某种参数化来描述的。当点不应该“从左到右”连接时,如何使用matlab中内置的样条线命令

到目前为止,我的代码并不多,它只是一个框,让你点击一些点

FigHandle = figure('Position', [15,15, 1500, 1500]);
rectangle('Position',[0,0,40,40])
daspect([1,1,1])
[x,y] = ginput;

所以我想我的问题是,如何处理x和y,这样你就可以用样条线来拟合它们,使它们“按时间顺序”相连。(最后,将最后一个连接到第一个)

下面是一个如何使用线性插值的示例:。这将使您得到与绘图(x,y)相同的结果。

这篇文章的想法是循环遍历每一对连续的点,并在这些点之间进行插值。您可能可以将其调整为使用样条曲线,但每次需要给它4点,这可能会导致问题,因为它们可能会加倍

要连接起点和终点,只需在插值之前执行以下操作:

x(end+1) = x(1);
y(end+1) = y(1);

对cscvn函数的探讨

curve = cscvn(points) 
返回经过给定序列点(:j),j=1:end的参数化变分或自然三次样条曲线(ppform)

这里有一个很好的例子:

我找到了使用cscvn函数的替代方法

使用半弧长参数化,我可以从阵列x和y创建样条曲线,如下所示:

diffx = diff(x);
diffy = diff(y);
t = zeros(1,length(x)-1);
for n = 1:length(x)-1 
    t(n+1) = t(n) + sqrt(diffx(n).^2+diffy(n).^2);
end
tj = linspace(t(1),t(end),300);

xj = interp1(t,x,tj,'spline');
yj = interp1(t,y,tj,'spline');
plot(x,y,'b.',xj,yj,'r-')
这创造了相当不错的轮廓


这样做的目的是利用这样一个事实,即平面中的曲线可以通过使用线段连接曲线上有限数量的点来近似创建多边形路径。使用这个,我们可以根据t参数化点(x,y)。因为我们只有几个点可以创建t,所以我们通过在它们之间添加线性间隔的点来创建更多的点。然后使用函数interp1,我们找到对应于这些线性间隔t,ti的x和y的中间值

事实上,我不认为你能这么容易地把它推广到样条曲线上。。。但它适用于线性插值,这是一个超过3个点的startA序列,可能没有单调方向。因此,我认为这是一条死胡同。当然,取四个点,用它们来确定中间点之间的线应该是什么样子的一般想法是有效的,但我不认为有一种简单的方法可以做到这一点。@DennisJaheruddin我同意。我很想知道
cscvn
使用了什么算法。+1这看起来是个不错的解决方案,但需要曲线拟合工具箱。看到一个不需要工具箱的答案还是很好的。嗯,是的,我同意,这将非常有效。我自己也有工具箱,所以这可能是一个很好的方法。非常感谢。如果要在点之间使用线性插值,这非常容易。只需使用
绘图(x,y)
。否则,您希望该行如何运行?我让它工作,但它产生了很多错误<代码>t需要初始化<代码>(diff(x))(n)。^2是Matlab中的语法错误。但是曲线看起来确实不错。如果你清理了代码,并添加了一个解释,解释它为什么工作,我将奖励奖金!嗯,我道歉,那太草率了。这是你深夜得到的答案。现在它肯定可以正常工作了,没有太多麻烦,我也添加了一个简短的解释。谢谢,我仍然不完全理解这行
t(n+1)=t(n)+sqrt(diffx(n)。^2+diffy(n)。^2)。你能再详细一点吗?是的,我一会儿再谈!我不得不考虑如何更详细地解释它,但包含了它的要点。这只是一个近似形式,因为我们没有x和y的解析表达式。是的,我想我已经算出了。它只是用欧几里德距离来近似曲线上的距离。可以对
x
y
进行插值,因为沿曲线
t
的距离总是单调增加的。它非常聪明。我认为这仍然需要一个更好的解释,但我会在可能的时候奖励奖金(仍然要等4个小时)。