Blob segmentation and writing it to folder

i have segmented few blobs using the below code
ccnt = 1;
for blob = 1 : n
thisBoundingBox = measurements(blob).BoundingBox;
[new_blob, pos] = imcrop(binaryImage, thisBoundingBox);
fileName = sprintf('FolderName/%d.bmp',ccnt);
imwrite(new_blob, fileName); ccnt = ccnt + 1;
end
When using the above code, i get all the blobs, but the order of the blobs written in the folder is not as i want
If my image is
i want each segmented blob to be written in the folder in the left to right order as
but i get it as
what should i do to get it in left to right order

 Accepted Answer

m = [...
1,2,3,4;
5,6,7,8;
9,10,11,12]
m2 = reshape(m', 1, []) % Transpose then reshape into row vector.
m =
1 2 3 4
5 6 7 8
9 10 11 12
m2 =
1 2 3 4 5 6 7 8 9 10 11 12

12 Comments

sir m is not a matrix, its an image.
It does not matter. I'm sure you know that an image IS a matrix, and vice versa : a matrix can be considered as an image.
sir, i have edited the question, please check if my input is such an image, what can be done to write the segmented blobs in left to right order, line by line
I'd use regionprops to get the centroids. Then knowing there are 2 blobs in each row, you can figure out which blob is in which quadrant.
props = regionprops(mask, 'Centroid', 'BoundingBox');
xy = vertcat(props.Centroid);
x = xy(:, 1);
meanx = mean(x)
y = xy(:, 2);
meany = mean(y);
for k = 1 : length(props)
thisx = x(k)
thisy = y(k)
if thisx < meanx && thisy < meany
% It's in quadrant 1
fileName = '1.png'
elseif thisx > meanx && thisy < meany
% It's in quadrant 2
fileName = '2.png'
elseif thisx < meanx && thisy > meany
% It's in quadrant 3
% etc.
end
croppedImage = imcrop(mask, props(k).BoundingBox)
imwrite(croppedImage, fileName);
end
See if you can finish it.
what if there are more than 2 blobs ( more number of rows and columns ). The number of blobs in the image keeps changing.
Sir, also that code didnt work for me. This is the order i got, but the first image should be STAR
Elysi then you didn't complete it correctly. Perhaps you were thrown off by the fact that there are there are two dots in the star. I handled that by filling the blobs. If you don't want it filled, then you can keep them using a few other special operations. Here is the way that you should have completed the code:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 22;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'image.png';
% Get the full filename, with path prepended.
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
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage);
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
grayImage = rgb2gray(grayImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
% grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the image.
subplot(2, 2, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
hFig = gcf;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
%--------------------------------------------------------------------------------------------------------
% SEGMENTATION OF IMAGE
% Get a binary image
binaryImage = ~imbinarize(grayImage);
% Get rid of the small dots in the star by doing a hole fill.
binaryImage = imfill(binaryImage, 'holes');
subplot(2, 2, 2);
% figure
imshow(binaryImage, []);
impixelinfo;
title('Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
%--------------------------------------------------------------------------------------------------------
% MEASUREMENT OF CENTROIDS
% Measurement of locations and assignment of file names.
props = regionprops(binaryImage, 'Centroid', 'BoundingBox');
xy = vertcat(props.Centroid);
x = xy(:, 1);
meanx = mean(x)
y = xy(:, 2);
meany = mean(y)
%--------------------------------------------------------------------------------------------------------
% PLOTTING AND SAVING
% Put up lines there.
yline(meany, 'LineWidth', 2, 'Color', 'r');
xline(meanx, 'LineWidth', 2, 'Color', 'r');
for k = 1 : length(props)
thisx = x(k);
thisy = y(k);
% Plot a red star at the centroid.
hold on;
plot(thisx, thisy, 'r*', 'MarkerSize', 15, 'LineWidth', 2);
if thisx < meanx && thisy < meany
% It's in quadrant 1
fileName = '1.png';
elseif thisx > meanx && thisy < meany
% It's in quadrant 2
fileName = '2.png';
elseif thisx < meanx && thisy > meany
% It's in quadrant 3
fileName = '3.png';
elseif thisx > meanx && thisy > meany
% It's in quadrant 4
fileName = '4.png';
end
croppedImage = imcrop(binaryImage, props(k).BoundingBox);
% Save the image.
fprintf('Blob #%d at (%.1f, %.1f) is being saved as %s.\n', k, thisx, thisy, fileName);
imwrite(croppedImage, fileName);
% Display images and labels.
subplot(2, 4, k+4);
imshow(croppedImage);
title(fileName, 'Color', 'r', 'FontSize', fontSize);
% Put a label over the blob in the upper right image.
subplot(2, 2, 2);
label = sprintf('Blob %d = %s', k, fileName);
text(thisx, thisy + 8, label, 'Color', 'r', 'FontSize', 13, 'FontWeight', 'bold', 'HorizontalAlignment', 'center');
end
impixelinfo;
You can see that the blobs have the correct filenames.
Sir the previous example (2 rows 2 columns) is working. But what if i have more number of rows or columns (number of rows and columns differ in images), like
where in the loop should i make the change to get the output as
Then you need to use kmeans on the x and y centroids to find out how many rows the blobs are in. Then get inbetween the centroids as the dividing lines.
[indexes, rowCentroids] = kmeans(yCentroid, 3);
If you don't know how many rows there are, you can also tell kmeans to figure it out for you.
For the general case of blobs scattered around like a shotgun blast, then I don't see any reason or need to sort them - it would just be arbitrary and the default ordering (top-down, left-to-right) is as good as any ordering.
sir how can kmeans find the number of rows?
In case of blobs scattered around like a shotgun blast, it doesnt matter, but i'm doing it in alphabets, then i need to identify the words, thats why
In that case, lines of text like scanned in from a page of a book, I'd use my attached demo. Basically get a vertical profile and threshold to find the number of lines.
I think you'd be best off picking a handwriting algorithm here: VisionBib
There are papers there that have successfully done it.
Sir i found a paper, using histogram peak

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!