How to crop and save objects from many images?

1 view (last 30 days)
Hi! I generated the code to threshold objects from an image using the colorThresholder. Can someone help me on cropping each seed per image and save them as individual seed in a designated folder? I'll be using the cropped images as trained images later on. Thank you so much! :)))
function [BW, masked RGBImage] = createMask(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the Thresholderapp. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 18-May-2023
% Convert RGB image to chosen color space
I = RGB;
% Define thresholds for channel 1 based on histogram settings
channel1Min = 31.000;
channel1Max = 122.000;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 19.000;
channel2Max = 96.000;
%Define thresholds for channel 3 based on histogram settings
channel3Min = 3.000;
channel3Max = 75.000;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channelMin ) & (I(:,:,1) <= channel1Max) &
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) &
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
%Initialize output masked image based on input image.
maskedRGBImage = RGB;
%Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end

Accepted Answer

Image Analyst
Image Analyst on 18 May 2023
Try this:
% Demo by Image Analyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear all;
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 16;
%===============================================================================
% Get the name of the image the user wants to use.
baseFileName = 'SB1.jpg';
folder = pwd;
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
%=======================================================================================
% Read in image.
rgbImage = imread(fullFileName);
% Get the dimensions of the image.
[rows, columns, numberOfColorChannels] = size(rgbImage)
% Display image.
subplot(2, 2, 1);
imshow(rgbImage, []);
impixelinfo;
axis on;
caption = sprintf('Original RGB Image\n%s', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Set up figure properties:
% Enlarge figure to full screen.
g2 = gcf;
g2.WindowState = "maximized";
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
%=======================================================================================
% Segment the image.
[mask, maskedRGBImage] = createMask(rgbImage);
% Get rid of any blobs less than 5000 pixels (there are 16 of them and are noise).
mask = bwareaopen(mask, 5000);
% Display image.
subplot(2, 2, 2);
imshow(mask, []);
impixelinfo;
axis on;
caption = sprintf('Mask Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
%--------------------------------------------------------------------------------------------------
% Get the bounding boxes and areas
props = regionprops(mask, 'BoundingBox', 'Area');
allAreas = sort([props.Area])
allBB = vertcat(props.BoundingBox);
%--------------------------------------------------------------------------------------------------
% Put boxes around each one.
subplot(2, 2, 3);
imshow(rgbImage, []);
impixelinfo;
axis on;
caption = sprintf('Original RGB Image\n%s', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
hold on;
for k = 1 : numel(props)
thisBB = allBB(k, :);
rectangle('Position', thisBB, 'EdgeColor', 'r')
% Label each with the blob number.
xt = thisBB(1);
yt = thisBB(2);
text(xt, yt, num2str(k), 'Color', 'r', 'FontSize', 17, 'FontWeight','bold', 'VerticalAlignment','bottom');
end
hold off;
%--------------------------------------------------------------------------------------------------
% Crop each blob into it's own image.
figure;
numRows = ceil(sqrt(numel(props)));
for k = 1 : numel(props)
thisBB = allBB(k, :);
thisBlob = imcrop(rgbImage, thisBB);
subplot(numRows, numRows, k)
imshow(thisBlob);
caption = sprintf('Seed #%d', k);
title(caption);
end
hold off;
function [BW, maskedRGBImage] = createMask(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the Thresholderapp. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 18-May-2023
% Convert RGB image to chosen color space
I = RGB;
% Define thresholds for channel 1 based on histogram settings
channel1Min = 31.000;
channel1Max = 122.000;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 19.000;
channel2Max = 96.000;
%Define thresholds for channel 3 based on histogram settings
channel3Min = 3.000;
channel3Max = 75.000;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) &...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) &...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
%Initialize output masked image based on input image.
maskedRGBImage = RGB;
%Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end
  5 Comments
Image Analyst
Image Analyst on 18 May 2023
@Maria Pauline Capiroso Yeah if you want to save the cropped images from this one image, you can just call imwrite in the loop I already gave you. The FAQ was if you want to do the same thing for lots of other images. You'd essentially put my code above into a function called something like ProcessOneImage(), and then call that from inside the loop over all images which you get from the FAQ.
If this Answer solves your original question, then could you please click the "Accept this answer" link to award the answerer with "reputation points" for their efforts in helping you? They'd appreciate it. Thanks in advance. 🙂 Note: you can only accept one answer (so pick the best one) but you can click the "Vote" icon for as many Answers as you want. Voting for an answer will also award reputation points.
Maria Pauline Capiroso
Maria Pauline Capiroso on 18 May 2023
I'm sorry, I forgot to accept immediately hehe. Thank you so much for the guidance. :))))

Sign in to comment.

More Answers (1)

Antoni Garcia-Herreros
Antoni Garcia-Herreros on 18 May 2023
Hello Maria,
You have two options, either crop the seed manually using drawrectangle or other ROI functions (drawpolygon)
Or create a cropping algorithm that creates a small image for each seed, the following would be a way to start:
clear all
folder_smallimage='C:\Users\...'; % Folder where your images will be stored
thr=50; % Threshold to filter small pixels, only retain the seed
RGB=imread('SB1.JPG');
% Convert RGB image to chosen color space
I = RGB;
% Define thresholds for channel 1 based on histogram settings
channel1Min = 31.000;
channel1Max = 122.000;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 19.000;
channel2Max = 96.000;
%Define thresholds for channel 3 based on histogram settings
channel3Min = 3.000;
channel3Max = 75.000;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) &(I(:,:,3) >= channel3Min ) &...
(I(:,:,3) <= channel3Max);
BW = sliderBW;
R=table2array(regionprops('table',BW,'Centroid','EquivDiameter','Area'));
R=R(R(:,1)>thr,:); % Filter out the small particles
Side_length=floor(1.5*max(R(:,4))); % Side length of the ROI
for i= 1:length(R) % Loop through seed
Small_IMG=BW(floor(R(i,3)-Side_length):floor(R(i,3)+Side_length),floor(R(i,2)-Side_length):floor( R(i,2)+Side_length));
% imshow(Small_IMG) % Plot if you want to doble check each ROI
% pause(0.1)
%
name=fullfile(folder_smallimage,[num2str(i) '.mat']);
save(name,'Small_IMG')
end
Hope this helps!

Community Treasure Hunt

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

Start Hunting!