MATLAB不会提取第一行和第一行。列因为矩阵尺寸

时间:2010-05-16 03:14:47

标签: matlab image-processing

我正在追踪一个抛向空中的物体,这个物体控制着一个抛物线模式。我通过一系列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

3 个答案:

答案 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));