Measurement in Images - Image Analysis
이전 댓글 표시
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
Iain
2013년 5월 21일
The images don't appear to work for me.
Kev
2013년 5월 21일
Matt Kindig
2013년 5월 21일
I'm a little unclear how step 5 is performed? Do you just mean that the fiber diameter is determined by scaling the distance perpendicular to the fiber thickness by the microscope scale (5.00 um)? Or is there something more tricky going on? Could you upload an image showing how you've defined the "fiber diameter"?
Matt Kindig
2013년 5월 21일
Also, will there be a single value of fiber diameter for each image, or do you have to take multiple thickness measurements? At what spacing do you need to take these measurements?
Kev
2013년 5월 21일
Image Analyst
2013년 5월 21일
Why do that instead of just taking the mean continuously over the entire fiber like my algorithm? Why get fewer diameter samples and be more sensitive to noise than just bulk processing the whole image to get the overall mean diameter?
kanu
2014년 2월 26일
I am working on retinal image. Can u tell me above measurement in images code. how you find out the diameter of any edges.
Image Analyst
2014년 2월 26일
Edges don't have any diameter. Retinal image analysis methods are explained in Section 20.5 here in VisonBib
kanu
2014년 2월 26일
edges diameter is change,i agree. but we can choose any place & calculate distance at different places of retinal vessel. I make my image smooth, find edges, brightness also adjust, binary conversion is also done. Now how to apply line tool on vessel edges is my problem? i think above kev's code will help me..plz image analyst try to solve my problem.
Image Analyst
2014년 2월 26일
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
2014년 2월 26일
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.
답변 (3개)
Image Analyst
2013년 5월 21일
0 개 추천
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
- Threshold the image
- 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.
- Sum up the image - this gives you the area of the fibers.
- Skeletonize the fibers with bwmorph('skel')
- Sum up that image - this gives you the total length of all the fibers.
- 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
Image Analyst
2013년 5월 22일
The concept behind background division is that if some pixel out at the corner has only 90% as much light as it should have, wouldn't you want to divide the image by 0.95 at that point to get it up to 100%? Of course you would. So you get an image that "should" be 100% completely uniform, but is not for some reason, such as the vignetting/shading that all camera systems have. Now you can divide and "fix" the shading problem.
So I think you understand. Basically we're going to assume the fibers are like a big rectangle. And if you know the area, and you know the length, you can calculate the width. Well it's not totally uniform in width since it might vary a pixel or two so this will give you the overall average width. So we fill it to get the area, then we skeletonize to get the length. Then divide to get the width. Make sense?
If it goes out of focus, then that could affect the width but it looks like those regions would be a very small portion so it won't affect the mean width very much. You could filter those out with a filter if you really thought they were going to cause a problem. But I doubt they will.
Image Analyst
2013년 5월 22일
Hard to disregard since they are burned into the image. Can you give an image with no annotation on it and maybe I can look at it later tonight.
Kev
2013년 5월 22일
Sean de Wolski
2013년 5월 22일
@IA, I disagree with your suggestion to use the sum of the pixels to count the length. This will give the city-block distance not the quasi-euclidian distance.
I would recommend either:
1) Take the 'perimeter' from regionprops and divide it by two
2) Use the geodesic distance transform on each fiber with one of the end points selected. The maximum value will be the length using whatever distance metric your want
Image Analyst
2013년 5월 22일
That's fine. I've not tried the geodesic transform yet - it's on my bucket list. It looks cool.
Jeff E
2013년 5월 22일
I would add bwarea to the list, as it is a bit more straightforward way to get the length for an entire skeletonized image.
Jeff E
2013년 5월 29일
If you look closely at your bw4_perim image, you'll notice that the mask is positive around most of the edges of the image. This results in much more perimeter being identified than there should be. You can alleviate this a bit by taking the logical inverse of your b4 image before applying bwperim, but you'll still have some extra perimeter.
The following lines of code identify the edges of your image, and remove them from your edge image:
edgemask = bwperim(true(size(bw4)));
bw4_perim = bw4_perim & ~edgemask;
Jeff E
2013년 5월 29일
Well, given the one link to the example image, this code works for me to obtain a fiber thickness that is pretty close to what I measure by hand:
I = imread('6202_D_1000_X_18wv_25_G_12_KV_15cm_0_05mlh_1.jpg');
g = rgb2gray(I);
K = imadjust(g,[0.55 0.69],[]);
bw = im2bw(K); %imshow(bw)
bw2 = imfill(bw,'holes');
bw3 = imopen(bw2, ones(5,5));
bw4 = bwareaopen(bw3, 40);
bw4_perim = bwperim(bw3);
edgemask = bwperim(true(size(bw4)));
bw4_perim = bw4_perim & ~edgemask;
fiber_length = bwarea(bw4_perim) / 2;
fiber_area = sum(sum(~bw4));
fiber_thickness = fiber_area / fiber_length ;
Image Analyst
2013년 5월 29일
Looks like it does a fairly good job!
Jeff E
2013년 5월 30일
The fiber_thickness is outputting pixels. From the picture you posted I am measuring the thickness at about 8 pixels, both manually and with the script. The scale bar, measured manually, is about 11 pixels for 5um, giving a pixel to micron ratio of 0.4545. You can apply a pixel to micron conversion like this:
pix_to_um = 0.4545;
fiber_thickness_microns = fiber_thickness * pix_to_um ;
This makes the fibers ~3.6 microns thick.
As to your second question, you can think of the imopen function used on a binary image as something that removes pixel structures that can't "fit" the given kernel. In this situation, you want the size of your kernel to be slightly larger than the largest white area you are trying to remove. I suggest you try playing around with the size of your kernel, and even to check out the strel function to define your kernels. I messed around with it a little bit, and larger kernels can adversely affect segmentation of fibers that run closely parallel to each other.
Jeff E
2013년 5월 30일
bwareaopen considers separately each contiguous white area in the image, and if the number of pixels in a given area is above the integer value given, the entire area is set to black. In the script above, the bwareaopen step removes any white area that is smaller than 40.
imopen is actually a sequential operation of an erosion then a dilation using the supplied matrix. Search the internet for "morphological opening" and check out the top few results.
I think the image you uploaded originally: http://s8.postimg.org/64tjh6fsl/6202_D_1000_X_18wv_25_G_12_KV_15cm_0_05mlh_1.jpg is at a different scale than your raw images. All my measurements and comments on kernel size are specific to that image.
Image Analyst
2013년 6월 7일
Filling could be a fix, like I originally suggested. I'mnot sure why you used imfill rather than thresholding teh EDT image like I suggested. I knew imfill() wouldn't work for your images because of the way they look (bright in the middle and going out to the edge of the image), and that's why I specifically didn't recommend imfill() and instead recommended using bwdist() instead. It's a little tricky (more than just a few steps) so perhaps you need my help. But I believe you can find the bright central core of the fibers and fill in just those. Please post your original images of the edge images you just referenced.
Image Analyst
2013년 6월 12일
That last image by imagej does not look like an edt image at all. I got a start on the edt code last week but didn't finish it. I've been doing an insane amount of world travel lately (Europe, US) and for the next two months (US, Europe, Asia, Latin America) so I don't have much time for in depth assistance of anyone.
Kev
2013년 6월 13일
Jeff E
2013년 6월 17일
I refer to step d as a "closing by area", and is achieved by using the bwareaopen function:
bw_output_image = ~bwareaopen(~bw_input_image, area_of_hole_to_remove) ;
Jeff E
2013년 6월 17일
My apologies for not being a bit more specific. The "area_of_hole_to_remove" should be more accurately named "area_below_which_all_holes_will_be_removed".
bwareaopen removes any contiguous objects below the specified area; the line of code I provided will remove any holes below the specified area.
Jeff E
2013년 6월 17일
Aha. I see. The below worked for me, with the caveat that the fibers along the edge of the image you uploaded didn't work due to the white border Matlab puts around figures. I'm hoping your actual image doesn't have that white border. You'll note this approach won't be perfect in that very small triangles won't be removed.
imgin = imread('abc2.png');
bwin = im2bw(imgin);
%make the size of this filter slightly larger than the width of your largest fiber
bw_open = imopen(bwin, strel('disk', 9));
bw_fin = imreconstruct(bw_open, bwin, 4);
Sean de Wolski
2013년 6월 26일
0 개 추천
Kev,
I think you would benefit a lot from the Vessel Tortuosity part of this webinar:
댓글 수: 31
Sean de Wolski
2013년 7월 2일
To do this you'll need to skeletonize the fiber, determine the local orientation at every few points, calculate the orthogonol orientation, and figure out how many pixels lie within this range that are part of the fiber.
I took one approach to it here:
Kev
2013년 7월 9일
Sean de Wolski
2013년 7월 9일
I'll look into this a little more when I get some free time.
Jeff E
2013년 7월 9일
In that little snippet of image, take the center white line as your object (with 8-connectivity). Use regionprops to get the orientation of the major axis of the fitted ellipse, subtract 90 degrees to get the minor axis. Then use that to calculate the slope, along with any point on the line to find two points to make a line, or intersections with the pink-black border.
Jeff E
2013년 7월 10일
Looking at that image you provided, the bwmorph operation 'spur' might also be helpful.
Kev
2013년 7월 11일
Kev
2013년 7월 17일
Saranya
2013년 12월 21일
Hi kev, in my project i want to measure the thickness of a single chromosome so that i can find the centromere location( where the thickness is shorter). I am in need of matlab coding for measuring the thickness..
Can you help me..
Kev
2014년 1월 13일
Soumitra
2014년 1월 15일
Hi Kev, I have a similar project like fiber diameter measurement where fibers are crossing each other at some places. I have tried filling up the fibers to get solid fiber and then get skeleton of that. I am lost after that. How can I get fiber diameter from there? Can you please help me?
Saranya
2014년 1월 23일
Hi kev, in my project i want to measure the thickness of a single chromosome so that i can find the centromere location( where the thickness is shorter). I am in need of matlab coding for measuring the thickness..
Can you help me.
this is one of my input image
Saranya
2014년 1월 30일
I want to compare 46 chromosome images. my input is Single chromosome.I tried on imageJ software before itself for Straightening purpose(to calculate the length). I should not use software for centromere identification.
Image Analyst
2014년 1월 30일
Please explain "I should not use software for centromere identification." Do you mean any software at all, or just some published software for expressly that purpose, or somebody elses' software (like what we might give you here or in the File Exchange)?
Saranya
2014년 1월 31일
Not like that sir. I was not supposed to use any softwares(like imageJ). I want to use only matlab coding to locate the centromere location.
Image Analyst
2014년 1월 31일
MATLAB is also software. Is that exempt from this "no software" rule?
Saranya
2014년 2월 1일
Ya.. I accept it sir. I want to use only MATLAB software for finding the centromere location
Image Analyst
2014년 2월 1일
Do you know how to program in MATLAB? I think you might have to do this on your own. I didn't see anything in the File Exchange. Check VisionBib for algorithms, and code one up.
Saranya
2014년 2월 1일
thank you sir. Am beginner to MATLAB sir. i will go through VisionBib..
Kev
2014년 2월 4일
kanu
2014년 2월 26일
hey,how u find out the distance between the line points. I am working on retinal image. Where i want to find out the diameter of vessels. can u please help me.
Image Analyst
2014년 2월 26일
I answered above, where you first asked: Retinal image analysis methods are explained in Section 20.5 here in VisonBib
Walter Roberson
2014년 3월 1일
kanu asked,
hey kev,how u find out the distance between the line points. I am working on retinal image. Where i want to find out the diameter of vessels. can u please help me.
Kev
2014년 3월 4일
sonya yasr
2014년 4월 7일
Can someone please answer my question? Its similar to above one.
lu sun
2015년 6월 23일
0 개 추천
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!
카테고리
도움말 센터 및 File Exchange에서 Image Segmentation에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


