我正在追踪一个抛向空中的物体,这个物体控制着一个抛物线模式。我通过一系列30张图片跟踪对象。我设法排除所有背景并保持对象明显,然后使用其质心来获取其坐标并绘制它们。现在我应该预测物体会落在哪里,所以我使用了polyfit& amp; polyval。问题是,MATLAB说:
???指数超过矩阵维度。
现在,质心创建了自己的结构,包含一行和两列。每当对象在循环中移动时,它仅更新第一行。
以下是代码的一部分:
For N = 1:30
.
.
.
x = centroid(1,1); % extract first row and column for x
y = centroid(1,2); % extract secnd row and column for x
plot_xy = plot(x,y)
set(plot_xy,'XData',x(1:N),'YData',y(1:N));
fitting = polyfit(x(1:N),y(1:N),2);
parabola = plot(x,nan(23,1));
evaluate = polyval(fitting,x);
set(parabola,'YData',evaluate)
.
.
end
我得到的错误信息是:
??? Index exceeds matrix dimensions.
似乎(1:N)导致问题。老实说,我不知道为什么,但是当我删除N时,对象与其点一起被绘制,但是多重拟合将不起作用。它给我一个错误说:
Warning: Polynomial is not unique; degree >= number of
data points.
> In polyfit at 72
如果我做了它(1:N-1)或其他东西,它会在它开始给我相同的错误(不是唯一的......)之前绘制更多的点。但我不能删除(1:N),因为我必须评估每个循环中多项式的系数(每个N的值),那么解决方案是什么?
编辑2:
这是我的更多代码
for N = 1:30
hold on
I = figure.image.(['j' num2str(N)]);
bw = (I);
imshow(bw)
ss = bwlabel(bw);
s = regionprops(bw,'centroid');
centroids = cat(1, s.Centroid);
hold(imgca,'on')
plot(imgca,centroids(1,1), centroids(1,2),'r*')
x = centroids(1,1);
y = centroids(1,2);
points = plot(x,y,'bo',x,y,'rx');
hold on;
for N>3
C1 = centroids(1,1);
C2 = centroids(1,2);
set(points,'XData',C1,'YData',C2);
poly = polyfit(C1,C2,2);
parabola = plot(C1,nan(size(centroids,1),1));
pval = polyval(poly,x);
set(parabola,'YData',pval);
pause(0.5)
end
end
编辑3
显示对象分散的代码:
poly = polyfit(C1,C2,2);
g = roots(poly);
v = max(g)
plot(xPlot,polyval(poly,xPlot),'y')
plot(v,'go')
由于xPlot正确绘制了抛物线,但对于g
(预测),一切都出错了......我使用错误的语法来获取最大值吗?
Alt text http://img706.imageshack.us/img706/6343/parabolaaaaa.jpg
我也意识到如果我把plot(g,'g--')
而不是v,我得到:
不知道我是否可以获得水平而不是垂直。然后我将有一条圆形线,预计抛物线会停止。
Alt text http://img101.imageshack.us/img101/6343/parabolaaaaa.jpg
答案 0 :(得分:1)
[回答编辑以反映更新]
在您的代码中,您使用了
C1=centroids(1,1);
C2=centroids(1,2);
在此步骤之后,C1和C2成为单元素标量。您可以使用size(C1)
和size(C2)
进行检查,这将返回[1 1]
作为答案。我猜你想要绘制第一个C1和C2点,然后将它一直扩展到元素对N.这不是必需的,plot
函数可以处理向量(甚至是矩阵,但是将显示为一系列情节。)
我不熟悉图像处理工具箱,我没有那个工具箱,所以我无法检查功能输出。但据我所知,你需要的是一个30行2列的质心位置数据阵列,你可以从中得到它在未知x处的位置曲线拟合。我删除了一些绘图功能;我相信这会使代码更清晰。
for N=1:30
I = figure.image.(['j' num2str(N)]);
bw=(I);
ss = bwlabel(bw);
s = regionprops(bw,'centroid');
centroids = cat(1, centroids, s.Centroid); %Concatenate s.Centroid below centroids
end
%At this point, "centroids" should be a 30-by-2 array
size(centroids) % check if the output from this is [30 2]
x=centroids(:,1);
y=centroids(:,2);
poly=polyfit(x,y,2); %poly is a vector of curve-fitted polynomial coefficients
pval=polyval(poly,x); %pval is a vector of curve-fitted values evaluated at x
parabola=plot(x,pval); %plot the parabola
要将抛物线的y位置设为x_i点,请使用polyval(poly,x_i)
。
特别注意cat
函数的正确语法; cat(A,B)连接A下面的B,你不能只使用一个参数cat
,就像你的原始代码一样。这可能是您头疼的根本原因,因为只有1个参数,MATLAB只需将“s.Centroid”作为新的“质心”数组,而不是将其添加到现有的“质心”数组下面。
回复编辑#3
在代码的这一部分
poly=polyfit(C1,C2,2); %'poly' is a vector of polynomial coefficients
g=roots(poly); %g solves for polynomial roots
v =max(g) %v is the largest root (assumed to be the expected ground-level destination)
plot(xPlot,polyval(poly,xPlot),'y') %plots polynomial at given x-values
%here, one expects to plot a point for the expected destination.
%the call to the plot function should follow syntax similar to the previous line
plot(v,'go') %plot function has syntax plot(x,y,options)
%therefore it should look like plot(v,polyval(poly,v),'go')
我添加了一些评论。问题在于您调用plot
来绘制预期目的地的行;语法似乎是错误的。如果仅给出1个数据参数,则MATLAB将给定数据假设为y值,使用其数组索引作为x值(即将y(1)绘制为1,将y(2)绘制为2等)。这不是你想要的变量v。
你也可以使用Jonas提到的plot(v,0,'go')
,但是仔细检查推断的多项式值是否实际接近于0会毫无伤害;)
答案 1 :(得分:1)
我怀疑你可能会把自己与x和y混淆,没有它们你可能会做得更好。如果我已正确理解您的意图,我将如何重写您的代码。特别注意重写的polyfit调用。我也认为你已经错误地编码了对nan的调用,所以我也“纠正了”:
For N=1:30
.
.
.
plot_xy=plot(centroid(1,1),centroid(1,2))
set(plot_xy,'XData',centroid(:,1),'YData',centroid(:,2);
fitting=polyfit(centroid(:,1),centroid(:,2),2);
parabola=plot(centroid(:,1),nan(size(centroid,1),1));
evaluate=polyval(fitting,centroid(1,1));
set(parabola,'YData',evaluate)
.
.
end
答案 2 :(得分:1)
如果我正确理解你想要做什么,这就是你的代码的样子:
%# if there is only one centroid per image, preassign centroid array like this
centroids = zeros(30,1); %# case A
%# if there can be any number of centroids per image, preassign like this
centroids = cell(30,1); %# case B
for N=1:30
hold on
I = figure.image.(['j' num2str(N)]);
bw=(I);
imshow(bw)
ss = bwlabel(bw);
s = regionprops(bw,'centroid');
%# for case A
centroids(N,:) = cat(1, s.Centroid);
%# for case B
centroids{N} = cat(1,s.Centroid);
hold(imgca,'on')
%# case A
plot(imgca,centroids(N,1), centroids(N,2),'r*')
%# case B
if ~isempty(centroids{N})
plot(imgca,centroids{N}(:,1), centroids{N}(:,2), 'r*');
end
%# I don't think the following lines do anything useful
x=centroids(1,1);
y=centroids(1,2);
points=plot(x,y,'bo',x,y,'rx');
%# update plots
drawnow
%# you can only do the fitting once you collected all centroids
end
%# case A - do nothing b/c centroids is already numeric
%# case B - catenate centroids to make a numeric array with 2 columns
centroids = cat(1,centroids{:});
C1=centroids(:,1);
C2=centroids(:,2);
%#set(points,'XData',C1,'YData',C2);
poly=polyfit(C1,C2,2);
%# you can use the output of polyval directly as y-coordinate
parabola=plot(C1,polyval(poly,C1));