MATLAB не будет извлекать первую строку и столбец из-за размеров матрицы - PullRequest
0 голосов
/ 16 мая 2010

Я отслеживаю объект, который брошен в воздух, и этот объект управляет параболическим узором. Я отслеживаю объект через серию из 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 (прогноз) все идет не так ... Использую ли я неправильный синтаксис для получения максимального значения?

Альтернативный текст http://img706.imageshack.us/img706/6343/parabolaaaaa.jpg

Я также понял, что если я поставлю plot(g,'g--') вместо v, я получу: Интересно, смогу ли я получить эту горизонталь вместо вертикали? Тогда у меня будет линия с кружком, где парабола, как предсказывают, остановится.

Альтернативный текст http://img101.imageshack.us/img101/6343/parabolaaaaa.jpg

Ответы [ 3 ]

1 голос
/ 16 мая 2010

Я подозреваю, что вы можете путать себя с x и y, и вы могли бы лучше без них. Вот как бы я переписал ваш код, если бы правильно понял ваши намерения. Обратите особое внимание на переписанный полифит. Я также думаю, что вы жестко закодировали вызов 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
1 голос
/ 17 мая 2010

Вот так должен выглядеть ваш код, если я правильно понимаю, что вы хотите сделать:

%# 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));
1 голос
/ 16 мая 2010

[Ответ отредактирован для отражения обновлений]

В своем коде вы использовали

C1=centroids(1,1);
C2=centroids(1,2);

После этого шага C1 и C2 становятся одноэлементными скалярами. Вы можете проверить это с помощью size(C1) и size(C2), которые вернут [1 1] в качестве ответа. Я предполагаю, что вы хотели построить первую точку C1- и C2, а затем расширить ее до пары элементов N. Это не обязательно, функция plot может обрабатывать векторы (и даже матрицы, но это появится как серия сюжетов).

Я не знаком с набором инструментов для обработки изображений, и у меня нет этого набора инструментов, поэтому я не могу проверить выходные данные функции. Но, насколько я могу судить, вам нужен 30-рядный массив столбцов с данными о положении центроида с двумя столбцами, из которого вы сможете изогнуть его положение в неизвестном х. Я удалил некоторые функции построения графиков; Я надеюсь, что это сделает код более понятным.

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) объединяет B ниже A, вы не можете использовать cat только с одним аргументом, как в исходном коде. Вероятно, это является основной причиной вашей головной боли, так как с одним аргументом MATLAB просто принимает «s.Centroid» в качестве нового массива «centroids» вместо добавления его ниже существующего массива «centroids».

Ответ на EDIT # 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.

Вы также можете использовать plot(v,0,'go'), как упомянуто Йонасом, но никогда не помешает дважды проверить, действительно ли экстраполированное полиномиальное значение близко к 0;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...