How to find area of holes in binary image?

11 vues (au cours des 30 derniers jours)
Konstantin
Konstantin le 12 Mai 2014
Commenté : Konstantin le 12 Mai 2014
Hi, I know this is pretty similar to a few questions before, but I am encountering a different problem not discussed so far.
The story: I have an image that i need to analyze for voids. All good an well and I successfully create the binary image (as seen from the screenshot). However, when I try to apply the imfill function on that picture to detect the holes, my script keeps on going. Keep in mind that original image is 385x875 px at 16 bit depth and the binary is at 2 bit...(doh..)
However, the script just keeps running and running with no sign of ever finishing. My task is to find the area (in pixels or mm) of the black region inside the white one. And having this problem is not much of a help to me.. Here's the script as well:
% start the timer
tic
% begin actual script
% loads image to matrix I
I = imread('scan0408.tif');
% convert the grayscale image to index image with 16-bit depth
[X, map] = gray2ind(I, 16);
% shows the new indexed image
imshow(X, map);
% convert the indexed image to a binary image with treshold of 0.38 (found
% to be the best treshold for these images)
BW = im2bw(X,map,0.38);
% show the binary image to compare to the original grayscale
imshow(X,map), figure, imshow(BW)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% takes the image and finds the locations of all the "holes". consequently,
% it fills the holes and prepares the image for eventual area calculation
BW2 = imfill(BW)
[BW2,locations] = imfill(BW)
BW2 = imfill(BW,locations)
BW2 = imfill(BW,'holes')
I2 = imfill(I)
BW2 = imfill(BW,locations,conn)
[gpuarrayI2]= imfill(gpuarrayI)
% end of actual script
% end the timer
toc
Thanks in advance!

Réponse acceptée

Image Analyst
Image Analyst le 12 Mai 2014
You forgot to attach the image. I can look at it after that. Is it closed off on the right edge, because it's not obvious? If so, I'd probably try to invert the image, then call imclearborder and then sum the pixels.
  3 commentaires
Image Analyst
Image Analyst le 12 Mai 2014
How about
holeArea = numel(BW) - bwarea(BW);
If you want whole pixels as the area instead of how bwarea does it (which counts partial pixels), then
BW = imclearborder(~BW);
holeArea = sum(BW(:));
Konstantin
Konstantin le 12 Mai 2014
I figured it out, but thanks a lot! Here's the solution I used (and you're absolutely right about the partial pixels of bwarea, but I don't really mind that (the more exact the result, the better).
% Script by Konstantin Rangelov
% May 12th, 2014
% start the timer
tic
% begin actual script
% loads image to matrix I
I = imread('scan0408.tif');
% convert the grayscale image to index image with 16-bit depth
[X, map] = gray2ind(I, 16);
% shows the new indexed image
% imshow(X, map);
% convert the indexed image to a binary image with treshold of 0.38 (found
% to be the best treshold for these images)
BW = im2bw(X,map,0.38);
% show the binary image to compare to the original grayscale
%imshow(X,map), figure, imshow(BW)
% takes the image and finds the locations of all the "holes". consequently,
% it fills the holes and prepares the image for eventual area calculation
% STATS = regionprops(BW, 'centroid', 'eulernumber', 'EquivDiameter')
% filling the holes inside the white segment
BW2=imfill(BW,'holes');
% showing the result
figure, imshow(BW2)
first plot (leftmost)
subplot(1,3,1), imshow('scan0408.tif')
STATS = regionprops(BW, 'centroid', 'eulernumber', 'EquivDiameter')
hold on
fsd=extractfield(STATS,'Centroid');
x1=fsd(1);
y1=fsd(2);
plot(x1,y1, 'b*')
title('Original Image')
second plot (middle)
subplot(1,3,2), imshow(BW)
STATS = regionprops(BW, 'centroid', 'eulernumber', 'EquivDiameter')
hold on
fsd=extractfield(STATS,'Centroid');
x1=fsd(1);
y1=fsd(2);
plot(x1,y1, 'b*')
title('Binary Image With Holes')
last plot (rightmost)
subplot(1,3,3), imshow(BW2)
STATS = regionprops(BW, 'centroid', 'eulernumber', 'EquivDiameter')
hold on
fsd=extractfield(STATS,'Centroid');
x1=fsd(1);
y1=fsd(2);
plot(x1,y1, 'b*')
title('Binary Image Without Holes')
calculating the area of the holes
noholes=bwarea(BW2); % white part without holes
withholes=bwarea(BW); % white part with holes
justholes=noholes-withholes; % total area in pixels of the holes alone
disp(['The area of the holes in the component is: ' num2str(justholes) ' px.'])
% end of actual script
end the timer
toc

Connectez-vous pour commenter.

Plus de réponses (0)

Community Treasure Hunt

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

Start Hunting!

Translated by