Changing Code Below from Only Detecting One RGB Channel to Detecting Specific RGB Range

2 visualizzazioni (ultimi 30 giorni)
Hello,
I am currently working on a system that acquires images from a set of webcams, stitches them together, and detects little pieces of simulated vegetation while naming the piece. I managed to get the image acquisition and stitching working, but for the color detection, I only figured out how to filter out and detect the colors in one channel. I want to be able to input a matrix of [R G B] to allow for more distinct patches of vegetation, but I am having some trouble with that. I also set up a Detector and blobAnalyser, but I am having trouble figuring out how to use them properly. My code below is only for one camera. If you know how to filter by [R G B] or how to make each loop faster, please let me know.
Thank you.
clc;
clear;
close all;
% Create objects for foreground detection and blob analysis
Detector = vision.ForegroundDetector('NumGaussians', 3, ...
'NumTrainingFrames', 40, 'MinimumBackgroundRatio', 0.7);
blobAnalyser = vision.BlobAnalysis('BoundingBoxOutputPort', true, ...
'AreaOutputPort', true, 'CentroidOutputPort', true, ...
'MinimumBlobArea', 400, 'MaximumBlobArea', 800);
% Create the webcam object.
cam1 = webcam(1);
% Set Resolutions
cam1.Resolution = '1920x1080';
% Create Readers
reader1 = cam1;
% Create the video player object.
frame2 = snapshot(reader1);
frameSize = size(frame2);
videoPlayer = vision.VideoPlayer('Position', [100 100 frameSize(2) 30]);
while ~isOpen(videoPlayer)
frame1 = frame2; %first frame
frame2 = snapshot(reader1); %next frame
% Show Frame
figure(1)
imshow(frame1)
hold on
% Filter out everything except blue objects bigger than 300px
diff_im = imsubtract(frame1(:,:,3), rgb2gray(frame1));
diff_im = medfilt2(diff_im,[3 3]);
diff_im = im2bw(diff_im,0.18);
diff_im = bwareaopen(diff_im,300);
stats = regionprops(diff_im,'BoundingBox','Centroid');
% Create Bounding Box and Text
for object = 1:length(stats)
bb = stats(object).BoundingBox;
bc = stats(object).Centroid;
rectangle('Position',bb,'EdgeColor','b','LineWidth',2)
plot(bc(1),bc(2),'-m+')
a = text(bc(1)+15,bc(2),strcat('x: ',num2str(bc(1)),' y: ',num2str(round(bc(2))),' Color: Blue'));
set(gca,'FontName','Times','FontWeight','bold','FontSize',12,'Color','blue')
end
end
% Clean up.
clear reader1;
release (videoPlayer);
release (Detector);

Risposte (1)

Chris Tronolone
Chris Tronolone il 25 Lug 2022
If this helps anyone else, I may have found a way bypass this problem. Instead of subtracting a gray image from the blue image, I made a for loop that uses i = 1:[number of pixel rows] and j = 1:[number of pixel columns] to index every possible pixel and then if loops that mark a pixel when the red, blue, and green channels are within set RGB ranges. The red, green, and blue channels are separated into individual arrays for the comparisons, but in the if loop, I believe that you could do pinkLow(1) <= frame(i,j,1) instead of pinkLow(1) <= r(i,j). Right now, the code is set for pink and orange with quite large RGB ranges, but I am still trying to tighten up those ranges. Please let me know if you have any tips for speeding up these loops, and I hope this code is helpful.
clc;
clear;
close all;
% Create the webcam object.
cam1 = webcam(1);
% Set Resolutions
cam1.Resolution = '1920x1080';
% Create Readers
reader1 = cam1;
% Create the video player object.
frame2 = snapshot(reader1);
frameSize = size(frame2);
videoPlayer = vision.VideoPlayer('Position', [100 100 frameSize(2) 30]);
% Define Color Ranges
pinkLow = [200,80,200];
pinkHigh = [255,160,255];
orangeLow = [140,90,0 ];
orangeHigh = [255,160,60];
while ~isOpen(videoPlayer)
frame1 = frame2; %first frame
frame2 = snapshot(reader1); %next frame
r = frame1(:,:,1);
g = frame1(:,:,2);
b = frame1(:,:,3);
figure(1)
imshow(frame1)
hold on
%{
diff_im = imsubtract(frame1(:,:,3), rgb2gray(frame1));
diff_im = medfilt2(diff_im,[12 12]);
diff_im = im2bw(diff_im,0.18);
%}
for i = 1:frameSize(1)
for j = 1:frameSize(2)
if pinkLow(1) <= r(i,j) && r(i,j) <= pinkHigh(1) && pinkLow(2) <= g(i,j) && g(i,j) <= pinkHigh(2) && pinkLow(3) <= b(i,j) && b(i,j) <= pinkHigh(3)
pinkDiff_im(i,j) = 1;
else
pinkDiff_im(i,j) = 0;
end
if orangeLow(1) <= r(i,j) && r(i,j) <= orangeHigh(1) && orangeLow(2) <= g(i,j) && g(i,j) <= orangeHigh(2) && orangeLow(3) <= b(i,j) && b(i,j) <= orangeHigh(3)
orangeDiff_im(i,j) = 1;
else
orangeDiff_im(i,j) = 0;
end
end
end
pinkDiff_im = bwareaopen(pinkDiff_im,300);
orangeDiff_im = bwareaopen(orangeDiff_im,300);
pinkStats = regionprops(pinkDiff_im,'BoundingBox','Centroid');
orangeStats = regionprops(orangeDiff_im, 'BoundingBox','Centroid');
for object = 1:length(pinkStats)
bb = pinkStats(object).BoundingBox;
bc = pinkStats(object).Centroid;
rectangle('Position',bb,'EdgeColor','magenta','LineWidth',2)
plot(bc(1),bc(2),'-m+')
a = text(bc(1)+15,bc(2),strcat('x: ',num2str(bc(1)),' y: ',num2str(round(bc(2))),' Color: Pink'));
set(gca,'FontName','Times','FontWeight','bold','FontSize',12,'Color','magenta')
end
for object = 1:length(orangeStats)
bb = orangeStats(object).BoundingBox;
bc = orangeStats(object).Centroid;
rectangle('Position',bb,'EdgeColor','red','LineWidth',2)
plot(bc(1),bc(2),'-m+')
a = text(bc(1)+15,bc(2),strcat('x: ',num2str(bc(1)),' y: ',num2str(round(bc(2))),' Color: Orange'));
set(gca,'FontName','Times','FontWeight','bold','FontSize',12,'Color','red')
end
hold off
end
% Clean up.
clear reader1;
release (videoPlayer);
release (Detector);

Categorie

Scopri di più su Image Processing and Computer Vision in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by