20
$\begingroup$

I have a picture:

enter image description here

The sunk area is a phase,and the bulged area in another phase.I want count the proportion of this two area.this is my method.First I get the mask by Image-Tool.

enter image description here

you can download to use it.

enter image description here

gra = GradientFilter[img, 2];
ImageCompose[img, {(comp = WatershedComponents[gra, mask]) // 
   Colorize[#, ColorRules -> {13 -> Transparent}] &, 0.6}]

enter image description here

Then the result is appear:

ComponentMeasurements[comp, "Count"] // SortBy[#, Last] & // 
    Values // {Total[Most[#]], Last[#]} & // #/Total[#] & // N

{0.547061, 0.452939}

But as you see,some unsatisfactory place like this place lead to the result is imprecise.:

enter image description here

BTW,the use of Image-Tool to pick so many component is very unadvisable.Can anybody give a more smart and more precise solution?

Update:

As the @SimonWoods 's request,I process the origional picture by PhotoShop and upload it:

enter image description here

$\endgroup$
  • 1
    $\begingroup$ Do you have a version of the image without the text and arrows overlay? $\endgroup$ – Simon Woods Feb 13 '16 at 14:56
  • $\begingroup$ @SimonWoods I'm sorry.This is original picture I get. $\endgroup$ – yode Feb 13 '16 at 15:23
  • 1
    $\begingroup$ @SimonWoods I uploaded the image without the text and arrows overlay just now. $\endgroup$ – yode Feb 13 '16 at 16:03
17
+50
$\begingroup$

Here's an idea that could work: The "Ferrite" areas have a border that's slightly darker than the background, while the area in between has a border that's slightly brighter than its neighborhood. So a filter that compares each pixel with the average brightness in the neighborhood, like an LoG filter should be a good start:

img = Import["http://i.stack.imgur.com/dMLH5.png"];    
(log = LaplacianGaussianFilter[img, 2]) // ImageAdjust

enter image description here

In this image, the border around the Fe-Areas is a bit lower than 0, the border around the "background" areas is a bit larger than 0, and the rest is around 0. So we can binarize this image to get the interior border:

filter = SelectComponents[#, "Length", # > 10 &] &;
bin = filter@MorphologicalBinarize[log, {0.05, 0.1}]

enter image description here

(Where I've used SelectComponents to remove some of the "noise" - you can play with additional criteria to get better results.)

And we can do the same thing with the sign flipped to get the "outer" border:

binO = filter@
  MorphologicalBinarize[ImageMultiply[log, -1], {0.05, 0.1}]

enter image description here

Now, pixels closer to the outer border are "background" pixels, and pixels closer to the inner border area "ferrite" pixels. So we simply calculate a Distance transform of the two border masks, and take the difference:

dt = DistanceTransform[ColorNegate[bin]];    
dtO = DistanceTransform[ColorNegate[binO]];    
(dtDiff = Image[ImageData[dtO] - ImageData[dt]]) // ImageAdjust

enter image description here

And mark pixels with distance difference < 0

HighlightImage[img, Binarize[dtDiff, 0]]

enter image description here

$\endgroup$
  • $\begingroup$ Wonderful work! $\endgroup$ – yode Feb 14 '16 at 3:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.