Core Optical, Inc.
MorphologicalProcessor GetBinaryObjects Method Industrial Strength, Scientific Grade
Retrieves a one-dimensional array of type BinaryObject representing the found binary objects in the input binary mask.

Namespace: PrecisionImage.BinarizationAndMorphology
Assembly: PrecisionImage (in PrecisionImage.dll) Version: 2.0.0.0 (2.0.0.0)
Syntax

public BinaryObject[] GetBinaryObjects(
	BinaryMask binaryMask
)

Return Value

An array of type BinaryObject containing the found objects in the input binary mask.
Exceptions

Remarks

Use this method to retrieve an array of found BinaryObject objects. Each individual object in binaryMask is stored as an entry in the returned array. An object is determined to be individual (discrete) if it exists as an isolated unmasked region in a BinaryMask image.

If the source BinaryMask image contains many discrete objects which are either in direct contact or are internconnected by a small number of pixels, discriminating between these objects can be improved by first applying the GetErodedBinaryMask(BinaryMask, BinaryMask) method prior to calling GetBinaryObjects(BinaryMask).

Examples

The following example automatically thresholds an image data channel, applies an erosion operation to the binary mask, and then displays the objects by tracing their outer contours over the original image using the Adorner class.
// Define the adorner class used to draw the outer contours: 
public class ObjectContourAdorner : Adorner
{
    List<PathGeometry>Contours;

     public ObjectContourAdorner(UIElement adornedElement)
        : base(adornedElement)
    {
        Contours = new List<PathGeometry>();
    }

    public void AddContour(Contour contour)
    {
        // Acquire the contour points: 
        Point[] points = contour.GetPoints();

        // Create a path figure object to define the contour: 
        PathFigure pathFigure = new PathFigure();

        // Add the first point in the contour as the path's starting point:
        pathFigure.StartPoint = points[0];

        // Add the rest of the points in the contour to the path: 
        for(Int32 x = 1; x < points.Length; x++)
        {
            LineSegment lineSegment = new LineSegment();
            lineSegment.IsSmoothJoin = true;
            lineSegment.Point = new Point(points[x].X, points[x].Y);
            pathFigure.Segments.Add(lineSegment);
        }

        // Set the IsClosed property to true:
        pathFigure.IsClosed = true;

        // Add the path figure to a new path geometry object: 
        PathGeometry pathGeometry = new PathGeometry();
        pathGeometry.Figures.Add(pathFigure);

        // Add the path geometry object to the adorner's collection:
        Contours.Add(pathGeometry);
    }

    protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);

        if (Contours.Count > 0)
        {
            foreach (PathGeometry contourGeometry in Contours)
            {
                drawingContext.DrawGeometry(null, new Pen(Brushes.Red, 1.5), contourGeometry);
            }
        }
    }
}

Now generate the binary objects from the source data and determine their outer contours:

using PrecisionImage;
using PrecisionImage.BinarizationAndMorphology;

// Acquire the image: 
Uri imageUri = new Uri("Objects.tif", UriKind.Relative);
TiffBitmapDecoder imageDecoder = new TiffBitmapDecoder(imageUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource sourceImage = imageDecoder.Frames[0];

// Display the source image:
image1.Source = sourceImage;

// Acquire the data from the image:
sourceData = new SourceData(sourceImage, GammaEncoding.None);

// Apply optimum global threshold to the data in channel 0: 
OtsuThresholder thresholder = new OtsuThresholder();
BinaryMask objectMask = thresholder.GetThresholdBinaryMask(sourceData, 0, HistogramResolution.EightBit);

// Perform a morphological opening operation: 
MorphologicalProcessor morph = new MorphologicalProcessor();
objectMask = morph.GetErodedBinaryMask(objectMask,  BinaryMask.GetCircularStructuringElement(2));
objectMask = morph.GetErodedBinaryMask(objectMask,  BinaryMask.GetCircularStructuringElement(2));
objectMask = morph.GetDilatedBinaryMask(objectMask, BinaryMask.GetCircularStructuringElement(2));

// Locate objects: 
BinaryObject[] binaryObjects = morph.GetBinaryObjects(objectMask);

// Display object perimeters (filter out small objects i.e. objects with an area less than 1000 pixels): 
ObjectContourAdorner adorner = new ObjectContourAdorner(image1);
foreach (BinaryObject binaryObject in binaryObjects)
{
    if (binaryObject.GetArea() > 1000)
    {
        adorner.AddContour(binaryObject.GetOuterContour());
    }
}

AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(image1);
adornerLayer.Add(adorner);

The following image pair illustrates the results from the above operation:

See Also