MATLAB is taking endless snapshots instead of a video, when trying to track colored object in webcam video.

3 vues (au cours des 30 derniers jours)
So I am trying to track 2 different colored objects in a webcam video, one yellow tag and one red tag. I assigned the webcam to a variable, then in a loop I have taken a snapshot, thresholded for both yellow and red tags, and then done further calculations that are required for my task (found border, calculated centroids, distances between tags, plotting centroids and distances).
The issue I am facing is when I run the code, instead of it playing a video where I can move the tags and it tracks them, it is creating a separate figure for each snapshot, so if I let it run for 30 seconds, there will be over 50 different snapshots produced in separate figures. I need this to be in a video format.
Furthermore, it is not plotting the centroid/distance figures onto the output, but I am assuming this problem is related to the video issue.
P.S. please see my earlier 2 questions if need more context, as they are both related to this same task.
Thanks for any help in advance!
The code is as follows:
clear all;
close all;
clc;
w = webcam;
webcam('Microsoft® LifeCam HD-3000','RESOLUTION','1280x720')
r = 0;
while(1)
RGB = w.snapshot;
%Yellow Tag
yellowChannel1Min = 0.000;
yellowChannel1Max = 255.000;
yellowChannel2Min = 71.000;
yellowChannel2Max = 255.000;
yellowChannel3Min = 0.000;
yellowChannel3Max = 40.000;
yellowSliderBW = (RGB(:,:,1) >= yellowChannel1Min ) & (RGB(:,:,1) <= yellowChannel1Max) & ...
(RGB(:,:,2) >= yellowChannel2Min ) & (RGB(:,:,2) <= yellowChannel2Max) & ...
(RGB(:,:,3) >= yellowChannel3Min ) & (RGB(:,:,3) <= yellowChannel3Max);
yellowBW = yellowSliderBW;
yellowMorph = imclose(yellowBW, ones(25));
%Red Tag
redChannel1Min = 71.000;
redChannel1Max = 255.000;
redChannel2Min = 0.000;
redChannel2Max = 41.000;
redChannel3Min = 0.000;
redChannel3Max = 54.000;
redSliderBW = (RGB(:,:,1) >= redChannel1Min ) & (RGB(:,:,1) <= redChannel1Max) & ...
(RGB(:,:,2) >= redChannel2Min ) & (RGB(:,:,2) <= redChannel2Max) & ...
(RGB(:,:,3) >= redChannel3Min ) & (RGB(:,:,3) <= redChannel3Max);
redBW = redSliderBW;
redSE = strel("rectangle",[5 4]);
redOpen = imopen(redBW, redSE);
redMorph = imclose(redOpen, ones(25));
%Find Border of images
yellowBorder = rangefilt(yellowMorph);
redBorder = rangefilt(redMorph);
yellowOverlay = imoverlay(RGB,yellowBorder,'r');
redYellowOverlay = imoverlay(yellowOverlay,redBorder,'g');
%Calculate Red& Yellow Tag Centroid Coordinates
[ri,rj] = find(redMorph);
riMean = mean2(ri);
rjMean = mean2(rj);
[yi,yj] = find(yellowMorph);
yiMean = mean2(yi);
yjMean = mean2(yj);
%Calculate Distances
dCityBlock = (abs(riMean - yiMean)) + (abs(rjMean - yjMean));
dChessboard = max(abs(riMean - yiMean), abs(rjMean - yjMean));
dEuclidean = sqrt((riMean - yiMean)^2 + (rjMean - yjMean)^2);
figure;
imshow(redYellowOverlay);
hold on;
plot(rjMean,riMean, 'g-x', 'LineWidth',5)
plot(yjMean,yiMean, 'g-x', 'LineWidth',5)
plot([rjMean,yjMean],[riMean,yiMean],'b','LineWidth',2);
dim = [0.15 0.3 0.3 0];
str = {['Red Tag Centroid i coordinates = ',num2str(riMean)],['Red Tag Centroid j coordinates = ',num2str(rjMean)],['Yellow Tag Centroid i coordinates = ',num2str(yiMean)],['Yellow Tag Centroid j coordinates = ',num2str(yjMean)],['City Block Distance = ',num2str(dCityBlock)],['Chessboard Distance = ',num2str(dChessboard)],['Euclidean Distance = ',num2str(dEuclidean)]};
annotation('textbox',dim,'String',str,'FitBoxToText','on','EdgeColor','green','Color','green');
subplot(3,1,1);
imshow(RGB);
subplot(3,1,2);
imshow(RGB);
end

Réponse acceptée

cr
cr le 1 Déc 2022
Modifié(e) : cr le 1 Déc 2022
Move call to figure() out of while loop. It opens a new window on each call in every iteration of the loop which is why your plots/images come on different windows. Also, once you create an image in a figure window you should try and call to the same parent axes. See calling imshow with parent property specified. imshow is slow. It would be smoother if you were to update underlying image data rather than calling imshow. E.g.:
Do the below once outside the loop
figure
h = imshow(IMG1);
when you need to update the image displayed to next frame, just do
h.CData = IMG2;
Regards
  8 commentaires
Ted
Ted le 5 Déc 2022
Great thank you, got it working perfectly now thanks to this.
Much appreciated!

Connectez-vous pour commenter.

Plus de réponses (0)

Produits


Version

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by