How to automatically get the area values from a plot (axis values?)?

1 view (last 30 days)
Faraz on 7 Mar 2014
Answered: Image Analyst on 7 Mar 2014
I have a plot figure which consists of 'blobs'. Each blob represents the area of a single character of the image on which it is based. Here is what the plot looks like:
This plot is generated by plotting the ``Area`` of ``regionprops`` of the original image.
Now each blob in the plot represents a single character and to segment it I have to manually enter the area value based on what I see on the plot.
For example the second 'blob' from the top has the area values between ``1800`` and ``2800``. Now by using the following code I can select only the character having area between 1800 and 2800.
bw_normal2 = im2bw(img, graythresh(img));
bw22 = imcomplement(bw_normal2);
bw3 = bwmorph(bw22, 'dilate');
[label2,n2] = bwlabel(bw3);
stats2 = regionprops(label2, {'Area', 'BoundingBox'});
figure, imshow(img);
for j=1:n2
hold on
area2 = stats2(j).Area;
if((1800 <= area2) & (area2 <= 2800))
'EdgeColor','r','LineWidth',2 );
This produces this image:
Thus showing correct segmentation.
Now the problem is that I have to automate this.
I did try a few attempts but they have failed. What I did is to first save the plot without the axis and borders so as not to corrupt the original data.
I then use ``imopen`` to seperate them slightly and then use ``bwlabel`` in hopes to correctly get their areas.
ploty = imcomplement(rgb2gray(imread('plot.jpg')));
bw = im2bw(ploty, graythresh(ploty));
se = strel('diamond', 3);
open = imopen(bw, se);
%open = bwmorph(bw, 'open');
[label, n] = bwlabel(bw);
stats = regionprops(label, 'Area');
But the problem is that the ``areas`` from this ``bwlabel`` are all messed up. Instead of the actual values almost all the areas are 29, one is 644 and the last is 1354. I think this was expected.
So how do I automatically get the axis values (begin and end) from the original graph?
I hope I was able to explain my problem correctly

Answers (1)

Image Analyst
Image Analyst on 7 Mar 2014
Uh, you don't want to do that. No need to mess around with morphological operations to extract blobs of certain areas (or any other attribute for that matter). What you want to do is to use find() to find indexes of blobs meeting the criteria, then use ismember if you want to extract only those blobs into a new labeled image. See my Image Segmentation Tutorial, "BlobsDemo": Here is the small relevant snippet.
% Now I'll demonstrate how to select certain blobs based using the ismember function.
% Let's say that we wanted to find only those blobs
% with an intensity between 150 and 220 and an area less than 2000 pixels.
% This would give us the three brightest dimes (the smaller coin type).
allBlobIntensities = [blobMeasurements.MeanIntensity];
allBlobAreas = [blobMeasurements.Area];
% Get a list of the blobs that meet our criteria and we need to keep.
allowableIntensityIndexes = (allBlobIntensities > 150) & (allBlobIntensities < 220);
allowableAreaIndexes = allBlobAreas < 2000; % Take the small objects.
keeperIndexes = find(allowableIntensityIndexes & allowableAreaIndexes);
% Extract only those blobs that meet our criteria, and
% eliminate those blobs that don't meet our criteria.
% Note how we use ismember() to do this.
keeperBlobsImage = ismember(labeledImage, keeperIndexes);
% Re-label with only the keeper blobs kept.
labeledDimeImage = bwlabel(keeperBlobsImage, 8); % Label each blob so we can make measurements of it
% Now we're done. We have a labeled image of blobs that meet our specified criteria.
If you want, you can extract just the areas without relabeling it:
selectedBlobsAreas = allAreas(keeperIndexes); % Get just the areas meeting criteria.

Community Treasure Hunt

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

Start Hunting!