I have a picture:
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.
you can download to use it.
gra = GradientFilter[img, 2];
ImageCompose[img, {(comp = WatershedComponents[gra, mask]) //
Colorize[#, ColorRules -> {13 -> Transparent}] &, 0.6}]
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.:
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:
Answer
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
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}]
(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}]
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
And mark pixels with distance difference < 0
HighlightImage[img, Binarize[dtDiff, 0]]
Comments
Post a Comment