代码之家  ›  专栏  ›  技术社区  ›  NLed

由于矩阵尺寸的原因,Matlab无法提取第一行和第一列

  •  0
  • NLed  · 技术社区  · 14 年前

    我跟踪一个抛向空中的物体,这个物体控制着一个抛物线图案。我正在通过一系列30张图片跟踪这个物体。我设法排除了所有的背景并保持物体的明显,然后用它的质心得到它的坐标并绘制出来。现在我要预测物体的下落位置,所以我使用了polyfit&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 回复  |  直到 12 年前
        1
  •  1
  •   Jonas    14 年前

    如果我正确理解了您想要做的事情,那么您的代码应该是这样的:

    %# 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));
    
        2
  •  1
  •   High Performance Mark    14 年前

    我怀疑你可能会把自己与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
    
        3
  •  1
  •   JS Ng    14 年前

    [回答已编辑以反映更新]

    在代码中,您使用

    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
    

    要获得抛物线在x_i点的y位置,请使用 polyval(poly,x_i) .

    请特别注意 cat 函数;cat(a,b)在a下面连接b,不能使用 只有一个参数,就像在原始代码中一样。这很可能是您头疼的根本原因,因为只有1个参数,matlab只将“s.centroid”作为新的“centroid s”数组,而不是将其添加到现有的“centroid s”数组之下。

    回复编辑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')
    

    我添加了一些评论。问题是你打电话的线路 情节 绘制预期的目的地;语法似乎错误。如果只给出1个数据参数,matlab假设给定数据为y值,使用其数组索引作为x值(即,在1处绘制y(1),在2处绘制y(2)等)。这不是你想要的变量v。

    您也可以使用 plot(v,0,'go') 正如jonas所提到的,但是如果外推的多项式值实际上接近0,则进行二次检查是不会有任何影响的;)