Вычисление длины маятника в движении

Этот пример показывает, как захватывать и анализировать изображения объекта в движении.

Этот пример захватывает изображения маятника в движении. Маятник состоит из синего мяча, прикрепленного к нейлоновой строке. Данные изображения получаются, когда маятник качается. После захвата изображения обрабатываются, чтобы определить длину маятника.

Изображения получают с помощью Image Acquisition Toolbox™ и анализируют с помощью Image Processing Toolbox™.

Получение изображений

Получите серию изображений для анализа.

% Access an image acquisition device.
vid = videoinput('winvideo', 1, 'RGB24_352x288');
vid.Timeout = 12;

% Configure object to capture every fifth frame.
vid.FrameGrabInterval = 5;

% Configure the number of frames to be logged.
vid.FramesPerTrigger = 50;

% Access the device's video source object selected for acquisition.
src = getselectedsource(vid);

% Configure the device to provide 30 frames per second.
src.FrameRate = '30';

% Open a live preview window. Focus camera onto a moving pendulum.
preview(vid);

% Initiate the acquisition.
start(vid);

% Extract frames from memory.
frames = getdata(vid);

% Remove video input object from memory.
delete(vid)
clear vid

% Display the first frame in the series.
imshow( frames(:, :, :, 1) );

% Display all acquired images.
imaqmontage(frames);

Выберите Необходимую область

Поскольку движение маятника ограничено верхней половиной ряда изображений. Создайте новую серию систем координат, которые содержат необходимую область.

Чтобы обрезать серию систем координат с помощью imcrop, сначала выполните imcrop на одной системе координат и хранить его выход. Затем создайте серию систем координат, имеющих размер предыдущего выхода.

% Determine the total number of frames acquired.
nFrames = size(frames, 4);

% Crop the first frame.
roi = [50 16 222 68];
firstFrame = frames(:,:,:,1);
frameRegion = imcrop(firstFrame, roi);

% Create a storage for the modified image series.
regions = repmat(uint8(0), [size(frameRegion) nFrames]);
for count = 1:nFrames,
    regions(:,:,:,count) = imcrop(frames(:,:,:,count), roi);
    imshow(regions(:,:,:,count));
end

Сегментируйте маятник в каждой системе координат

Поскольку маятник намного темнее фона, маятник может быть сегментирован в каждой системе координат путем преобразования системы координат в полутоновую, ее порогового значения и удаления фоновых структур.

% Initialize array to contain the segmented pendulum frames.
segPend = false([size(frameRegion, 1) size(frameRegion, 2) nFrames]);
centroids = zeros(nFrames, 2);
structDisk = strel('disk', 3);

for count = 1:nFrames,
    % Convert to grayscale.
    fr = regions(:,:,:,count);
    gfr = rgb2gray(fr);
    gfr = imcomplement(gfr);

    % Experimentally determine the threshold.
    bw = im2bw(gfr, .7);
    bw = imopen(bw, structDisk);
    bw = imclearborder(bw);
    segPend(:,:,count) = bw;
    imshow(bw);
end

Найти центры каждого сегментированного маятника

Форма сегментированного маятника в каждой системе координат не является серьезной проблемой, поскольку центр маятника является единственной характеристикой, необходимой для определения длины маятника.

% Calculate the pendulum centers.
for count = 1:nFrames,
    property = regionprops(segPend(:, :, count), 'Centroid');
    pendCenters(count,:) = property.Centroid;
end

% Display the pendulum centers and adjust the plot.
figure;
x = pendCenters(:, 1);
y = pendCenters(:, 2);
plot(x, y, 'm.');
axis ij;
axis equal;
hold on;
xlabel('x');
ylabel('y');
title('Pendulum Centers');

Вычисление длины маятника

Подгонкой окружности через центры маятника можно вычислить длину маятника. Переписать основное уравнение круга:

  • (x-xc) ^ 2 + (y-yc) ^ 2 = радиус ^ 2

где (xc, yc) - центр, с точки зрения параметров a, b и c:

  • x ^ 2 + y ^ 2 + a * x + b * y + c = 0

где:

  • a = -2 * xc

  • b = -2 * yc

  • c = xc ^ 2 + yc ^ 2 - радиус ^ 2.

Решая для параметров a, b и c с помощью метода наименьших квадратов, вышеописанное уравнение может быть переписано как:

  • a * x + b * y + c = - (x ^ 2 + y ^ 2)

который также может быть переписан как:

  • [а; b; c] * [x y 1] = -x ^ 2 - y ^ 2

Это уравнение можно решить в MATLAB ® с помощью оператора обратной косой черты (\).

% Solve the equation.
abc = [x y ones(length(x),1)] \ [-(x.^2 + y.^2)];
a = abc(1);
b = abc(2);
c = abc(3);
xc = -a/2;
yc = -b/2;
circleRadius = sqrt((xc^2 + yc^2) - c);

% Circle radius is the length of the pendulum in pixels.
pendulumLength = round(circleRadius)
pendulumLength =

   253
% Superimpose results onto the pendulum centers
circle_theta = pi/3:0.01:pi*2/3;
x_fit = circleRadius*cos(circle_theta) + xc;
y_fit = circleRadius*sin(circle_theta) + yc;
plot(x_fit, y_fit, 'b-');
plot(xc, yc, 'bx', 'LineWidth', 2);
plot([xc x(1)], [yc y(1)], 'b-');
titleStr = sprintf('Pendulum Length = %d pixels', pendulumLength);
text(xc-110, yc+100, titleStr);