Measurement in Images - Image Analysis

53 views (last 30 days)
Kev
Kev on 21 May 2013
Answered: lu sun on 23 Jun 2015
Hello there!
I'm faced with a project in which I'm assigned to have matlab calculate the fiber diameter from the images. We obtain these images from electron microscope. I've used ImageJ software for image processing and then calculating the diameter from the software. However, the process is tedious since we have lots of images and would like to automate the process. I've learned the macro feature in ImageJ, but it is the obtaining points from the picture that takes much of the time. Please, have a look at the sample microscopic image so you can have an idea. :)
Here is our process for ImageJ software:
1) Make image Smooth
2) Find Edges
3) Adjust Brightness/Contrast
4) Turn image into Binary
5) Use the line tool to calculate the distance b/w two fiber edges (the line is positioned perpendicularly along the fiber)
6) Paste the data into Excel and then calculate the fiber diameter by subtracting the distance along the line. We differentiate by black area and white area.
I can macro/automate part 1-4, but we would like to automate entire process, or most of it since we have lots of images.
So far, I have learned image processing in matlab. I have learned bw functions, gaussian filter, finding edges using different methods (prewitt, canny, sobel and etc.) I have no idea on how I can make matlab identify the fibers in images and then calculate the fiber diameter and then export it. Do note, there are regions where fiber overlaps with other fibers and that regions is little messy so calculate, so we avoid/reject that portions. I have attached a binarized image for your reference. I'd very much appreciate your input.
Sincrely,
Kev
  12 Comments
Image Analyst
Image Analyst on 26 Feb 2014
Sorry but this is not an easy problem to solve. Why do you think people work months or years on algorithms and then publish them? If there are publications on it, it's not trivial. It's not like some 5 minute demo I can whip together for you. You'll have to put a lot of work into it. Good luck.
Image Analyst
Image Analyst on 26 Feb 2014
I outlined my approach in my answer below but Kev chose to use a different approach. I'll help with code if it doesn't take too much time, so if you have something simpler in the future I can write some code, or if it's complicated I may just outline an algorithm, like I did for Kev, or point you to a place where you can find the answer, such as web sites like VisionBib which has virtually every paper on image processing ever published.

Sign in to comment.

Answers (3)

Image Analyst
Image Analyst on 21 May 2013
That's not how I'd do it. First of all I wouldn't do edge detection - it's not necessary since the image is already basically an edge image. So first I'd take a blank shot (no fibers) and get a blank background image. Then smooth it and divide your test images by it to correct for local non-uniformities in the illumination. Then, for each background corrected image
  1. Threshold the image
  2. Fill in the centers of the fibers using the Euclidean Distance Transform (performed by bwdist()) and identifying regions with a small mean EDT value. Now you have solid fibers and you're practically done.
  3. Sum up the image - this gives you the area of the fibers.
  4. Skeletonize the fibers with bwmorph('skel')
  5. Sum up that image - this gives you the total length of all the fibers.
  6. Divide the area by the length to give you the mean width of the fibers.
The only somewhat tricky part is step #2. For that you need to find non-zero parts of the EDT image and use regionprops to find out the mean value of each region. Central fiber shafts will have small mean EDT values while the background will have huge mean EDT values. Then use ismember to extract out only the small regions - see my image segmentation tutorial at http://www.mathworks.com/matlabcentral/fileexchange/?term=authorid%3A31862 for an example of how to use ismember to do filtering like that. So after this you have a binary image of the center shafts of the fibers and you can use that to fill in the rest of the fibers. Then it's ultra simple to do steps 3-6 after that.
  34 Comments
Kev
Kev on 19 Jun 2013
Edited: Kev on 19 Jun 2013
Hi Jeff,
I've implemented above lines and it is giving me solid fibers. Sincere thanks to Image_Analyst and JeffEA for ongoing support.
I'm looking to compare diameter obtained using EDT with manual (ImageJ or most accurate) method because I do see variations in diameter values. Some areas in same fibers I have ~ 10 % of error difference when compared with ImageJ. I'd like to mathematically determine whether this method is reliable and accurate. :)
If Matlab is calculating euclidean distance, should it not be very very same throughout the fiber? Suppose fiber is at 45 angle, is EDT calculated along 45 angle(perpendicularly) or horizontally?
How can I display text or annotation on image? I would not like to embed it in the image, just show the diameter after the line is drawn. I can pass string using text or annotation, but not integer/double values. I spent couple hours researching this. I must be missing something.
Lastly, how can I run the loop? How can I have a user draw a line over an image as many times as he wants.
Please have a look at the code. I'd appreciate if you can test it and provide feedback.
Thanks!
https://dl.dropboxusercontent.com/u/44449411/fib_dia.m
https://dl.dropboxusercontent.com/u/44449411/fib.zip (Sample Images)
Kev
Kev on 24 Jun 2013
Edited: Kev on 24 Jun 2013
Found EDT Is calculated along straight line. I had know about it but wasn't too sure how it applied to fibers at angles. EDT falls short when fibers are at angles. The differences error is about 4.5 %.
I'm was thinking of another method. I found number of elements that are above zero, which means these are positive or on pixels and I can count these pixels to determine diameter, but it only works great if fiber is totally vertical.
Algorithm looks at the matrix of fibers. The matrix is created in rectangle form. It can work if I can make the matrix form from line to line only, so that way I can see positive pixels to count those pixels.
I'm looking to extract values along the line, so I can count on pixels to determine fibers. If you know any function or method, please share it.
I've figured out the for loop and text situation, btw.
extract_pos_element = bw_fin( pos(3): pos(4) , pos(1): pos(2));
on_pixels = extract_pos_element;
on_pixels_rows = sum(on_pixels~=0,2);
avg_row = sum(on_pixels_rows);
avg_dia_in_pixels = avg_row/size(on_pixels_rows, 1);
dia_in_microns = avg_dia_in_pixels/6.2;
disp(dia_in_microns)
http://pasteboard.co/B1ePevI.png [extracting elements along the line like box drawn.]
EDT findings:

Sign in to comment.


Sean de Wolski
Sean de Wolski on 26 Jun 2013
Kev,
I think you would benefit a lot from the Vessel Tortuosity part of this webinar:
  31 Comments
Kev
Kev on 4 Mar 2014
I used the improfile function. You can have a line, for example, have a line along the image and you can obtain the data that correspond to individual points on the line. If you have a binary image, then you'd be able to identify the beginning and ending point. I hope this makes sense.

Sign in to comment.


lu sun
lu sun on 23 Jun 2015
Hello Kev, I believe you have already solved this issue. Now I have the similar problems as you, could you maybe send me the code how you did this? It would be very appreciated!
Thank you!

Community Treasure Hunt

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

Start Hunting!