Measure perimeter of black edge in Mathematica
Edit
You should be aware that there are 2 basic ways of counting perimeter pixels: 4-ways neighbors or 8-ways neighbors. The difference is about whether counting or not the yellow pixels in this figure:
If you want to count them, then almost manually:
i = Import["http://i.stack.imgur.com/7jt0I.gif"];
mask = Complement[Partition[#, 3] & /@ ({0, 0, 0, 0, 1, 0, 0, 0, 0} -
RotateLeft[{1, 0, 0, 0, 0, 0, 0, 0, 0}, #] & /@ Range[9]), {Array[0 &, {3, 3}]}];
ip = ImagePad[i, 10, RGBColor[0.4980 {1, 1, 1}]];
is = Binarize@
ImageSubtract[ HitMissTransform[ColorConvert[ip, "Grayscale"], mask, .1],
ImageSubtract[HitMissTransform[ColorConvert[ip, "Grayscale"], mask, .1],
HitMissTransform[ColorConvert[ip, "Grayscale"], mask, .8]]]
ImageMeasurements[is, "Total"]
14715
If you don't want to count the diagonal neighbors, then we change the mask to consider only four neighbors per pixel:
i = Import["http://i.stack.imgur.com/7jt0I.gif"];
mask = {{{0, -1, 0}, {0, 1, 0}, {0, 0, 0}}, {{0, 0, 0}, {-1, 1, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, 1, -1}, {0, 0, 0}}, {{0, 0, 0}, { 0, 1, 0}, {0,-1, 0}}};
ip = ImagePad[i, 10, RGBColor[0.4980 {1, 1, 1}]];
is = Binarize@
ImageSubtract[ HitMissTransform[ColorConvert[ip, "Grayscale"], mask, .1],
ImageSubtract[HitMissTransform[ColorConvert[ip, "Grayscale"], mask, .1],
HitMissTransform[ColorConvert[ip, "Grayscale"], mask, .8]]];
ImageMeasurements[is, "Total"]
10411
I'm not experienced in image processing so it may be naive but who knows :)
pro = EdgeDetect@pic
pro// ImageData // Flatten // Count[#, 1] &
15683
Which is counts of white pixels, it can be first rough estimate of perimeter I think. Well that's just a shot :)
Since I'm a beginner I do not know how to hide outer circle which should not add to the counts. But:
pro // ImageData // Dimensions
{828, 828}
So I can calculate its perimeter :D and subtract from our result:
15683 - 828 Pi // N
13081.8
How about using
img=Import["http://i.stack.imgur.com/7jt0I.gif"];
comp=ClusteringComponents[img];
ComponentMeasurements[comp, "PerimeterLength"]
(*{1 -> 6392, 2 -> 16402, 3 -> 16364}*)
(*Here not only black/white transitions but all included not OP asked for!*)
Edit 1
Correction based on the comments below!
(*Towards the solution*)
(*Find and filter gray and black components*)
{compGray, compWhite} = {comp /. { 2 -> 0, 3 -> 0},
comp /. { 1 -> 0, 3 -> 0}};
GraphicsRow [{Colorize[compGray] , Colorize[compWhite]}]
(*Convert to image*)
imgGray = ColorNegate@Binarize@(compGray // Image);
imgWhite = ColorNegate@Binarize@(compWhite // Image);
(*Find bounding circle information*)
circleInfo = ComponentMeasurements[imgGray,
{"BoundingDiskCenter",
"BoundingDiskRadius"}][[All, 2]]
circle Center and radius
{{{414.499, 413.501}, 413.999}}
-
(*Detect edges of white components*)
edges = Closing[EdgeDetect[imgWhite], 2];
(*Subtract the bounding circle from curves of white component*)
iCurves = Rasterize[Show[{edges,
Graphics[{Black, Thickness[0.003],
Circle @@ # & /@ circleInfo}]}]]
(*Calculate the total perimeter*)
ImageMeasurements[Thinning@Binarize@iCurves, "Total"]
The result
10358