MATLAB Answers

Kev
1

How to fill inside of binary region?

Asked by Kev
on 12 Sep 2013
Latest activity Edited by Ashish Uthama on 14 Oct 2013
Dear Matlab Community,
I'm working on a tool which measures the fiber diameter automatically. These fibers are made from PLA (Polylactic acid). There are different weight percent of this acid. And we are using optical microscope to obtain the image.
So I'm struggling with filling the fibres. I'm making a separate post because I haven't received any reply on there. I have used suggested technique in which you would reconstruct the image based on mask and marker image. This appears to work on 90% of the images. After completing the code, we were looking to calibrate and validate the script with images of known diameter. However, this technique doesn't appear to work on this glass fiber and we would also like to make this program more robust so that one doesn't have to change any values if the diameter is in very high or low range (5 microns/15 or 10).
Sorry for making a new post, but I'd really appreciate if there is any technique like inversing the image and filling the empty region. In one book, the author uses following approach, but I'm unable to achieve part D. http://s18.postimg.org/8cjie7qpl/abc.png
Sincerely, Kev

  2 Comments

I'm not fully sure what you are attempting to do, but I believe that imclearborder() should work for your case D.
doc imclearborder
Kev
on 12 Sep 2013
Hi Matt!
I tried imclearborder and it doesn't appear to work. It looks like it clears border of the image. It didn't remove outside of the edge.
What I'm attempting to do is, I want to make the fibers solid. Due to possible light issue, the fiber are not 100% solid and they need to be filled. From solid fiber I make a skeleton image.
For example: I have this binary image: http://snag.gy/WIYx0.jpg and I want to fill the inside of fiber that is white. I'd like to fill it without morphological tool.

Sign in to comment.

2 Answers

Answer by Image Analyst
on 12 Sep 2013

Try tophat and bottomhat filters:
clc;
format compact
close all;
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
% Read in a standard MATLAB gray scale demo image.
folder = 'D:\Temporary stuff\';
baseFileName = 'WIYx0.jpg.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% File doesn't exist -- didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, '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.
% numberOfColorBands should be = 1.
[rows, columns, numberOfColorBands] = size(grayImage);
if numberOfColorBands > 1
% It's not really gray scale like we expected - it's color.
% Convert it to gray scale by taking only the green channel.
grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
se = strel('Octagon', 3);
th = imtophat(grayImage, se);
% Display the image.
subplot(2, 2, 2);
imshow(th, []);
title('Top Hat Image', 'FontSize', fontSize);
bh = imbothat(grayImage, se);
% Display the image.
subplot(2, 2, 3);
imshow(bh, []);
title('Bottom Hat Image', 'FontSize', fontSize);
out = uint8((double(th)+double(bh))/2);
% Display the image.
subplot(2, 2, 4);
imshow(out, []);
title('Output Image', 'FontSize', fontSize);

  3 Comments

Kev
on 20 Sep 2013
Dear ImageAnalyst,
Please don't be offended if I don't accept the answer. I appreciate your input very much, but it doesn't serve my purpose. I've tried above program, and I was able to get the same results. My question is, I'm being asked to find a way that could generalize the process of filling in the fiber. At presently, I'm using imreconstruct (with marker and mask to fill in the fiber. And these parameters had to be changed when glass fiber image we wanted to use for calibration was much larger in diameter.
Let me add, I don't have background in image processing. I only reference books to gain understanding. The tool I created to measure fiber width/diameter is working. This was my approach:
  1. Import RGB image
  2. Convert into Grayscale and apply median filtering
  3. Convert Image into Binary (level = graythresh)
  4. Then using marker and mask image reconstruct the image
  5. Get skeleton of this (reconstructed image - solid - no gap between two edges).
  6. Calculation part I'll summarize in short: make a linear fit (at certain region) - I have slope of this linear fit. I can make a perpendicular line from the reciprocal of a liner fit (line).
  7. And I used improfile (along that perpendicular line) to get the coordinates of the edge.
Is this approach good? What are your thoughts? The only issue we're facing is, my supervisor would like to use different technique than imreconstruct. Sorry for the long post, but I really appreciate your help.
This is the original image from microscope. https://dl.dropboxusercontent.com/u/44449411/6202D_1000X_18wv_25G_12KV_15cm_0.05mlh_1.jpg
This is the image we used for calibration. https://dl.dropboxusercontent.com/u/44449411/1.jpg
Suppose you have that original image and you would like to fill in the gap when the image is converted into binary, how would you approach? Would there be any way to "fill" in the region for any size of the gap? Is there any approach in (grayscale or RGB) image processing that could fill the inside of the fiber?
Sincerely,
Kev
Did you code it up? If so, attach your program and your image with larger fibers. Click the paper clip icon. I can't get to dropbox from within my company - they banned it.
Kev
on 25 Sep 2013
Dear Image Analyst,
I've sent you a zip file containing my code and sample images. I discussed with my supervisor and he said we can build a GUI to adjust the marker and mask image parameters (when required). So, I've designed the GUI. I was wondering if you can advice me on how I can approach this. I'm looking into building basic GUI to learn. But if you look at my code, will I require to make drastic changes if I were to add GUI? Sorry for asking stupid questions. I appreciate your kind response.
Sincerely,
Kev

Sign in to comment.


Answer by Ashish Uthama on 14 Oct 2013
Edited by Ashish Uthama on 14 Oct 2013

How about connected component analysis? Use regionprops to obtain properties of each of the connected components (i.e areas of white surrounded by black). The 'Eccentricity' stat looks promising in differentiating 'line like' vs 'blob like'.
A quick attempt:
im = imread('/tmp/t.png');
imtool(im);
bw = all(im,3);
imshow(bw);
Obtain all stats for the connected components
stats = regionprops(bw,'all');
% There ought to be something 'different' about the inside of the tubes.
% 'Eccentricity' seems promising from the description in the doc.
eThresh = 0.99; %higher => more 'line' like
lineStats = stats([stats.Eccentricity]>eThresh);
%%Fill up the line like regions
bwFilled = bw;
lineLocations = {lineStats.PixelIdxList};
lineLocations = cell2mat(lineLocations');
bwFilled(lineLocations) = false;
imshowpair(bw, bwFilled);
As you can see, this is not perfect. Maybe you could come up with your own stat based on the pixel list of the connected component to better identify regions 'inside' the tube. (There will always be an edge case where human intervention would be required - consider multiple parallel tubes with the spacing between them being equal to the tube thickness).

  0 Comments

Sign in to comment.