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$
3
  • 1
    $\begingroup$ Do you have a version of the image without the text and arrows overlay? $\endgroup$ Feb 13, 2016 at 14:56
  • $\begingroup$ @SimonWoods I'm sorry.This is original picture I get. $\endgroup$
    – yode
    Feb 13, 2016 at 15:23
  • 1
    $\begingroup$ @SimonWoods I uploaded the image without the text and arrows overlay just now. $\endgroup$
    – yode
    Feb 13, 2016 at 16:03

1 Answer 1

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["https://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$
1
  • $\begingroup$ Wonderful work! $\endgroup$
    – yode
    Feb 14, 2016 at 3:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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