Convex Hull Based Shape Parameters edit page

Stretch a rubber band around a grain and let it snap tight: what you get is the convex hull. A convex grain is its own hull, however large or elongated it is. A bay or inlet leaves a gap between the grain and its hull, so comparing the two isolates lobateness: departure from a convex outline.

This page assumes the direct measurements introduced in Shape Parameters. The shapes below are artificial, chosen so that each measure has something to react to.

% import the artificial grain shapes
plottingConvention.default('y↑→x');
mtexdata testgrains silent

% select and smooth a few interesting grains
grains = smoothBoundary(grains('id',[2 3 9 11 15 16 18 23 31 33 38 40]),3);

Boundary smoothing is not optional here. On an unsmoothed square grid every boundary segment is horizontal or vertical. The perimeter then measures the cityblock distance and comes out too long, while the convex hull cuts the corners. The difference between the two would be dominated by the grid. For very small grains even smoothing does not save it, and the numbers below should not be trusted.

hull returns the hulls as grains, so everything that works on grains works on them.

% compute convex hull grains
chGrains = grains.hull;

% plot the original grains
plot(grains,'micronbar','off'), legend off

% and on top of them the convex hull
hold on
plot(chGrains.boundary,'lineWidth',2,'lineColor','r')
text(grains,arrayfun(@num2str,grains.id,'UniformOutput',false))
hold off

Where a grain is convex the red line follows its outline; where it is indented the line cuts across. The labels are grain ids used in the table below. Hulls may overlap even when the grains do not. A hull outline no longer separates two grains. The second phase of every hull boundary segment is therefore set to 'notIndexed'.

Four ways to measure an indentation

The relative difference between the perimeter of the grain and that of its hull reacts most strongly to thin, narrow indentations - a crack that does not quite cut the grain in two adds a great deal of perimeter and almost no area. The result, deltaP, is a dimensionless percentage.

deltaP = 100 * (grains.perimeter-chGrains.perimeter) ./ grains.perimeter;

paris, the Percentile Average Relative Indented Surface, compares the same two perimeters relative to the hull and doubles that ratio. It is the conventional name in the literature, and grains.paris computes it directly.

paris = 200 * (grains.perimeter - chGrains.perimeter) ./ chGrains.perimeter;

Comparing the areas instead of the perimeters reacts to broad, shallow lobes - a big bite out of a grain, which changes the area a lot and the perimeter hardly at all. The result, deltaA, is 100 times one minus the quantity often called solidity, the grain area divided by its hull area.

deltaA = 100 * (chGrains.area - grains.area) ./ chGrains.area;

Since the two react to different kinds of indentation, combining them gives radiusD, a measure that responds to both.

radiusD = sqrt(deltaP.^2 + deltaA.^2);

Compare the measures

The table makes the values behind the colour maps explicit. A zero in a perimeter-based column means that the outer outline is convex. deltaA is zero only when the grain fills its hull, with no hole. deltaP and deltaA are below 100, whereas paris has no upper bound despite being reported as a percentage.

indentationSummary = table(grains.id,grains.hasHole,deltaP,grains.paris,...
  deltaA,radiusD,'VariableNames',...
  {'grainId','hasHole','deltaP','paris','deltaA','radiusD'})
indentationSummary =
  12×6 table
    grainId    hasHole    deltaP    paris     deltaA     radiusD
    _______    _______    ______    ______    _______    _______
       2        false     1.5993    3.2506    0.94143    1.8558 
       3        false     22.441    57.867     5.2569    23.048 
       9        false     45.108    164.35     8.6773    45.935 
      11        false     6.3239    13.502     8.4411    10.547 
      15        false     35.089    108.11     23.228     42.08 
      16        false     8.1283    17.695     11.266    13.892 
      18        false     27.222    74.809     41.946    50.005 
      23        true      1.5738     3.198     16.206    16.282 
      31        true      1.6069    3.2663     31.506    31.547 
      33        false       45.5    166.97     34.684    57.212 
      38        false     4.8281    10.146     16.891    17.567 
      40        false      14.32    33.426     31.414    34.524

Drawn side by side on the same shapes, the measures separate narrow from broad indentations:

plot(grains,deltaP,'layout',[2 2],'micronbar','off')
mtexTitle('deltaP')

nextAxis
plot(grains,grains.paris,'micronbar','off')
mtexTitle('paris')

nextAxis
plot(grains,deltaA,'micronbar','off')
mtexTitle('deltaA')

nextAxis
plot(grains,radiusD,'micronbar','off')
mtexTitle('radiusD')
mtexColorbar

The first two maps rank the grains identically, as they must, being the same ratio written two ways - only the scale differs, paris running to 167 where deltaP stops at 46. The third map ranks them differently: the lobed grain scores 45 on deltaP against 9 on deltaA, all perimeter and almost no missing area, while the two discs with a hole score 1.6 on deltaP - as convex as the plain disc - and 16 and 32 on deltaA. radiusD puts both kinds high, which is what combining them is for.

The discs with holes are worth a second look, because they show what these measures are and are not counting. A hole and an inclusion are the same enclosure viewed from opposite sides. It is not an indentation of the outer outline, so the perimeter-based measures ignore it; paris explicitly removes inclusion loops before it measures. The area-based measure cannot ignore it, since the hull contains the hole and the grain does not. If a hole is not what you mean by lobateness, use deltaP or paris; if it is, use deltaA.

Which measure to report otherwise depends on the process being described. A dissolution front eats broad bays and shows up in deltaA; a partly healed fracture is a thin slot and shows up in deltaP.

These values also depend on pixel spacing and boundary smoothing. Use the same smoothBoundary settings for every map being compared, report them with the segmentation and resolution, and state the formula because other software uses names such as convexity and solidity for several different ratios.

References

Next

A convex hull discards every indentation. The Projection Parameters page instead keeps the width of each grain as a function of direction and develops shape-preferred orientation from those widths.

Citing this page. This page is part of the documentation of MTEX, a free and open source MATLAB toolbox for analyzing and modeling crystallographic textures. It was written by The MTEX Developers and is published at https://mtex-toolbox.github.io/HullBasedParameters.html. If you use MTEX, or reuse text or figures from this page, in your research, please cite

F. Bachmann, R. Hielscher, H. Schaeben: Texture Analysis with MTEX - Free and Open Source Software Toolbox, Solid State Phenomena 160 (2010), 63-68. 10.4028/www.scientific.net/SSP.160.63

BibTeX
@article{bachmann2010mtex,
  author  = {F. Bachmann and R. Hielscher and H. Schaeben},
  title   = {Texture Analysis with MTEX - Free and Open Source Software Toolbox},
  journal = {Solid State Phenomena},
  volume  = {160},
  pages   = {63-68},
  year    = {2010},
  doi     = {10.4028/www.scientific.net/SSP.160.63},
  url     = {https://doi.org/10.4028/www.scientific.net/SSP.160.63}
}

Other papers describing specific MTEX methods are listed under Publications — please cite the one that best fits your application. The MTEX source code is licensed under the GNU General Public License v2.0; the text and figures of this documentation are licensed under CC BY 4.0, which permits reuse — including by automated systems — provided The MTEX Developers and this page are credited.