Tracking motion of particles: using edge detection and blob analysis?

6 visualizaciones (últimos 30 días)
Butterflyfish
Butterflyfish el 18 de Jun. de 2024
Respondida: Image Analyst el 18 de Jun. de 2024
Hi,
I would like to track particles in a stack of 500 images (451 x 191 x 500).
The raw images look like this:
I would like to detect, select a few different ROIs (for example, one of the very bright particles, and some of the darker 'dots' in this picture) and track their motion through the 500 frames.
I have tried using the canny edge detector, followed by a blob analysis to track it. Not too sure if this is the best way to go.
So far, I have this script:
data = load(data);
for i = 1:size(data, 3)
BWStack(:, :, i) = edge(data(:, :, i), 'Canny');
end
% Select ROI interactively
figure;
imshow(BWStack(:, :, 1));
h = drawpolygon();
roiMask = createMask(h);
% Crop the ROI from each frame
ROIStack = false(size(BWStack));
for i = 1:size(BWStack, 3)
ROIStack(:, :, i) = BWStack(:, :, i) & roiMask;
end
% Convert the ROIStack to uint8
ROIStack_uint8 = uint8(ROIStack) * 255;
% Motion tracking using foreground detection
foregroundDetector = vision.ForegroundDetector('NumGaussians', 5, 'NumTrainingFrames', 150);
% Initialize video player
videoPlayer = vision.VideoPlayer('Position', [100, 100, 500, 400]);
% Initialize a blob analysis system object
blobAnalysis = vision.BlobAnalysis('BoundingBoxOutputPort', true, ...
'AreaOutputPort', true, ...
'CentroidOutputPort', true, ...
'MinimumBlobArea', 1);
pauseDuration = 0.01; % Adjust this value to control playback speed
% Initialize
pointTracker = vision.PointTracker('MaxBidirectionalError', 2);
trajectories = cell(size(ROIStack_uint8, 3), 1);
trackerInitialized = false;
outputTrajectories = {};
for i = 1:size(ROIStack_uint8, 3)
% Detect foreground
foreground = foregroundDetector(ROIStack_uint8(:, :, i));
% Perform blob analysis to find connected components
[objArea, centroids, bbox] = step(blobAnalysis, foreground);
% Ensure centroids have two columns
if ~isempty(centroids) && size(centroids, 2) >= 2
if ~trackerInitialized
% Convert centroids to double
centroids = double(centroids);
% Initialize the point tracker with the centroids in the first frame
initialize(pointTracker, centroids, ROIStack_uint8(:, :, i));
trackerInitialized = true;
else
% Track the points
[points, validity] = step(pointTracker, ROIStack_uint8(:, :, i));
% Store valid points
trajectories{i} = points(validity, :);
% Append valid points to output trajectories
if ~isempty(points(validity, :))
outputTrajectories = [outputTrajectories; num2cell([repmat(i, sum(validity), 1), points(validity, :)])];
end
% Draw the points on the frame if there are valid points
if ~isempty(points(validity, :))
out = insertMarker(ROIStack_uint8(:, :, i), points(validity, :), '+', 'Color', 'red');
else
out = ROIStack_uint8(:, :, i);
end
end
else
% If no centroids are found, use the previous frame's points
if i > 1 && ~isempty(trajectories{i-1})
points = trajectories{i-1};
trajectories{i} = points;
% Append previous points to output trajectories
outputTrajectories = [outputTrajectories; num2cell([repmat(i, size(points, 1), 1), points])];
out = insertMarker(ROIStack_uint8(:, :, i), points, '+', 'Color', 'red');
else
out = ROIStack_uint8(:, :, i);
end
end
% Draw a box around the detected objects
Ishape = insertShape(out, 'Rectangle', bbox);
% Display the frame
step(videoPlayer, Ishape);
% Pause to control playback speed
pause(pauseDuration);
end
release(videoPlayer);
release(pointTracker);
% Display the trajectories
figure;
hold on;
for i = 2:size(trajectories, 1)
if ~isempty(trajectories{i})
plot(trajectories{i}(:, 1), trajectories{i}(:, 2), 'r.-');
end
end
title('Particle Trajectories');
xlabel('X Position');
ylabel('Y Position');
hold off;
% Write trajectories to CSV
cell2csv('trajectories.csv', outputTrajectories, {'Frame', 'X', 'Y'});
% Function to write cell array to CSV
function cell2csv(fileName, cellArray, headers)
fid = fopen(fileName, 'w');
if ~isempty(headers)
fprintf(fid, '%s,', headers{1:end-1});
fprintf(fid, '%s\n', headers{end});
end
for row = 1:size(cellArray, 1)
fprintf(fid, '%d,%f,%f\n', cellArray{row,:});
end
fclose(fid);
end
It seems to track many different points on the ROI but not continuously.
Example dataset 'data.mat' available here.
Any help and advice much appreciated!

Respuestas (1)

Image Analyst
Image Analyst el 18 de Jun. de 2024
The Computer VIsion Toolbox has some tracking functionality, though I haven't used it.

Categorías

Más información sobre Tracking and Motion Estimation en Help Center y File Exchange.

Productos


Versión

R2024a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by