MATLAB is taking endless snapshots instead of a video, when trying to track colored object in webcam video.
2 views (last 30 days)
Show older comments
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
0 Comments
Accepted Answer
cr
on 1 Dec 2022
Edited: cr
on 1 Dec 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 Comments
More Answers (0)
See Also
Categories
Find more on Computer Vision with Simulink in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!