Tracking motion of particles: using edge detection and blob analysis?
    4 vues (au cours des 30 derniers jours)
  
       Afficher commentaires plus anciens
    
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.
Any help and advice much appreciated!
0 commentaires
Réponses (1)
  Image Analyst
      
      
 le 18 Juin 2024
        The Computer VIsion Toolbox has some tracking functionality, though I haven't used it.
0 commentaires
Voir également
Catégories
				En savoir plus sur Computer Vision with Simulink dans Help Center et File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

