Click or drag to resize

IMcRegions2Holes Property

Holes of all features

Namespace:  MediaCy.IQL.Features
Assembly:  MediaCy.IQL.Features (in MediaCy.IQL.Features.dll) Version: 10.0.6912.0
Syntax
VB
Property Holes As IMcRegions
	Get
	Set

Property Value

Type: IMcRegions

Implements

IMcRegionsHoles
Remarks
The concept of a "hole" is one inherently related to a bit mask representation of regions (see McRegions for more discussion of bit mask versus polygon region representations). A hole is a set of connected background pixels completely surrounded by a set of connected foreground pixels (a "blob"). A hole in a bit mask is not the same as a "nested" region feature. A nested feature is any whose boundary is enclosed within some other feature's boundary. A hole boundary is nested within the boundary of its enclosing blob, but usually there is no feature corresponding to this hole boundary (exception: when the mcofDefaultXorOnMerge bit of McFeatures.OptionsFlag is on then a hole bound will normally also correspond to a nested feature boundary). The relationships between nested region features are identified by the NestedWithin property and a set of related measurements. The Holes property is a McRegions that holds the holes that appear in the "union bit map" of all features. The union bit map is always available via the McFeatures.AccessMaskedImageData, McFeatures.GetLineSegments or McFeatures.CreateFeatureMask methods, but its connected regions (blobs) are guaranteed to exactly correspond to the region features only if the the mcofKeepRegionsAsUnion bit of the McFeatures.OptionsFlag property is on (and it is off by default). Thus when the mcofKeepRegionsAsUnion bit of the McFeatures.OptionsFlag property is off (as it is by default), the Holes property (and measurements such as mRgnNumHoles) will have a non-zero count of Holes only under certain circumstances. Even if mcofKeepRegionsAsUnion is off, holes may be initially present when a McRegions is filled from a bit mask via the McFeatures.SetFromMask method or via the Threshold property (an instance of McThreshold, which can segment image data into foreground and background pixels based on image luminance or color). These holes will persist as long as no operation is performed that requires recomputing the union bit mask; that is, so long as no features are added or changed. Holes may also appear in the union bit mask if the mcofDefaultXorOnMerge bit of McFeatures.OptionsFlag is on or if one or more features have the mcfsfXorOnMerge bit of their McFeatures.FeatureStatusFlags on. In this case, when the union bit mask is created by merging the pixels under and interior to the region features, the merge is done using an XOR rather than an OR bitwise operation. The effect is to create a hole in the union bitmap where one feature overlies another. Even if the mcofDefaultXorOnMerge bit of McFeatures.OptionsFlag is off holes may appear in the union bit mask if features overlap (e.g., 3 overlapping circles may leave a hole in the single, merged blob created by the three circles). Furthermore, you may directly introduce holes into the union bit mask by assigning to the Holes property. Again, if mcofKeepRegionsAsUnion is off these holes will persist only so long as no changes are made to the features. When the Holes property McRegions object is accessed, it is updated (if necessary) to reflect the current state of holes in the union bit mask. The Holes McRegions object is not updated at any other time, even if holes change. The Holes property McRegions object is a child of the McRegions object exposing the property. The Holes' McFeatures.SourceFlags property is filled with the index of the parent feature for each hole region feature or -1 if the upper-left pixel of a hole is not on or interior to a feature boundary (this my happen in the default situation where the mcofKeepRegionsAsUnion bit is clear). The Holes object always has its mcofKeepRegionsAsUnion bit on, and its mcofConnect8 OptionsFlag is the inverse of the parent McRegions'. The Holes property is also exposed as a measurement, mrRgnHolesAsRegions. And several other measurements are also based on the Holes property: mRgnNumHoles, mRgnHoleArea, mRgnHoleAreaRatio, miRgnHoleParent, mvRgnHoleIndices.
Examples
VB
'This is NestingAndHolesSamples.bas
'
'These samples illustrate holes and nested region features, and
'the measurements you can make about them.

Option Explicit

'Note: the Nesting.jpg example image is a good one for these examples
Private Function uLoadExampleImage(Optional strImage As String = "Nesting.jpg") As Boolean
    If MsgBox("Open example image?", vbYesNo) = vbYes Then
        Images.Open Path + "Images\" + strImage
    End If 'user wants to open an example image
    'Else leave the ActiveImage alone
    If ActiveImage Is Nothing Then
        MsgBox "There is no ActiveImage, so the example cannot run."
    End If 'don't have image
    uLoadExampleImage = ActiveImage Is Nothing
End Function 'uLoadExampleImage

Private Function uDetectRegionsWithHoles()
    With ActiveImage.RegionFeatures
        .Threshold.Execute 'get some regions
        If .Count = 0 Then
            MsgBox "This image's AOI has no regions.  Pick an image AOI with bright blobs that have holes in them."
            uDetectRegionsWithHoles = True 'no regions
            Exit Function
        End If 'no regions
        If .Holes.Count = 0 Then
            MsgBox "This image's regions have no holes.  Pick an image with bright regions that have holes in them."
            uDetectRegionsWithHoles = True 'no regions
            Exit Function
        End If 'no holes
    End With 'ActiveImage.RegionFeatures
End Function 'uDetectRegionsWithHoles

'Show all hole boundaries
Public Sub ShowAllHoles()
    If uLoadExampleImage Then Exit Sub
    If uDetectRegionsWithHoles() Then Exit Sub
    With ActiveImage.RegionFeatures
        Dim mcregionsHoles As McRegions
        Set mcregionsHoles = .mrRgnHolesAsRegions.value
        'Set mcregionsHoles = .Holes 'this would also work
        With mcregionsHoles
            'Show the holes
            .AutoDisplay = True 'turn on display
            With .DisplayedObjects
                .SetColors &HFFFF00  'show in cyan
                .SetBorderWidth 2 'with fat boundary
            End With 'mcregionsHoles.DisplayedObjects
        End With 'mcregionsHoles

            'For regions with holes, show the hole count
        .SourceFlags = .mRgnNumHoles
        With .DisplayedObjects(McOpNE(.mRgnNumHoles, 0))
            .SetLabelText "N holes: %d", _
                mcsltDisplaySourceFlags + mcsltLabelTopleft + mcsltLabelInside, &HFF00FF  'magenta
        End With

        MsgBox "Regions with holes are labeled with N of holes." + vbCrLf + _
            "Holes are show in cyan." + vbCrLf + "When you press OK, they will disappear."
        ' .DisplayedObjects.SetLabelText "", mcsltLabelHidden 'hide the labels
        mcregionsHoles.AutoDisplay = False 'hide the holes
    End With 'ActiveImage.RegionFeatures
End Sub 'ShowAllHoles

'Show outermost hole boundaries only
Public Sub ShowOutermostHoles()
    If uLoadExampleImage Then Exit Sub
    If uDetectRegionsWithHoles() Then Exit Sub
    With ActiveImage.RegionFeatures
            'Make a copy of the Holes regions
        Dim mcregionsHolesCopy As McRegions
        Set mcregionsHolesCopy = .mrRgnHolesAsRegions.value.Duplicate
            'Find all regions that are not outermost regions
        Dim selNotOutermost As Variant
        Set selNotOutermost = McOpNOT(McOpEQ(.mRgnNestingDepth, 0))
        If McSqueezeSelector(selNotOutermost).VectorLength <> 0 Then
                'Remove holes that are not children of outermost regions
            Dim mcobjNotOutermost As McObject
            Set mcobjNotOutermost = McObjectTemp(.mvRgnHoleIndices.ValueMcObject.SelectedValues(selNotOutermost))
                'Note the SelectedValues in the above statement returns an array of Variant's
                'The McObjectTemp function unwinds this into a form that can be used by RemoveFeatures,
                'below, as a selector for the hole features to remove.
            mcregionsHolesCopy.RemoveFeature mcobjNotOutermost
                'Show the remaining holes
            With mcregionsHolesCopy
                .AutoDisplay = True 'turn on display
                With .DisplayedObjects
                    .SetColors &HFF00FF  'show in magenta
                    .SetBorderWidth 2 'with fat boundary
                End With 'mcregionsHolesCopy.DisplayedObjects
                MsgBox "Holes of outermost regions only are shown (in magenta)." + vbCrLf + "When you press OK, they will disappear."
                .AutoDisplay = False 'hide the holes
            End With 'mcregionsHolesCopy
        Else 'there are no nested holes
            MsgBox "All regions in this image's AOI are outermost regions."
        End If 'no nested holes
    End With 'ActiveImage.RegionFeatures
End Sub 'ShowOutermostHoles

'Highlight regions with the biggest 1/2 of the holes
Public Sub HighlightRegionsWithTheBiggestHoles()
    If uLoadExampleImage Then Exit Sub
    If uDetectRegionsWithHoles() Then Exit Sub
    With ActiveImage.RegionFeatures
        Dim mcregionsHoles As McRegions
        Set mcregionsHoles = .mrRgnHolesAsRegions.value
        'Set mcregionsHoles = .Holes 'this would also work
        Dim selHolesSortedBySize As McObject
        Set selHolesSortedBySize = McSort(mcregionsHoles.mRgnArea, False) 'Descending sort
        Dim selLargestHalfOfHoles As Variant
        selLargestHalfOfHoles = selHolesSortedBySize.SelectedValues(McOpFillIn(0, mcregionsHoles.Count / 2))
        Dim selFeaturesWithLargestHoles As Variant
        selFeaturesWithLargestHoles = .miRgnHoleParent(selLargestHalfOfHoles)
        'Note that the miRgnHoleParent measurement is non-standard in that it is an array
        'of length .Holes.Count, and NOT an array of length .Count as sandard measurements are.
        'The miRgnHoleParent measurement array associates with each .Hole feature to give
        'the feature index of its surrounding parent region (of which we want to highlight
        'those surrounding the biggest 1/2 of the holes).
            'Highlight features around the biggest holes
        With .DisplayedObjects(selFeaturesWithLargestHoles)
            .SetColors &HFF00FF  'magenta
            .SetBorderWidth 2 'and wider
        End With
        MsgBox "Regions surrounding the largest 1/2 of the holes are shown highlighted."
    End With 'ActiveImage.RegionFeatures
End Sub 'HighlightRegionsWithTheBiggestHoles

'Show nesting depth of all region features
Public Sub ShowNestingDepthOfAllRegionFeatures()
    If uLoadExampleImage Then Exit Sub
    If uDetectRegionsWithHoles() Then Exit Sub
    With ActiveImage.RegionFeatures
            'Show the nesting depth in green text
        .SourceFlags = .mRgnNestingDepth
        .DisplayedObjects.SetLabelText "D: %d", _
            mcsltDisplaySourceFlags + mcsltLabelTopleft + mcsltLabelInside, &HFF00&  'green

        MsgBox "Regions are labeled with the nesting depth of the region."
    End With 'ActiveImage.RegionFeatures
End Sub 'ShowNestingDepthOfAllRegionFeatures

'Label regions with two or more nested children and highlight the nested child regions
Public Sub LabelRegionsWithTwoOrMoreNestedChildren()
    If uLoadExampleImage Then Exit Sub
    If uDetectRegionsWithHoles() Then Exit Sub
    With ActiveImage.RegionFeatures
            'Find all regions that have two or more nested children
        Dim selMultiChildren As Variant
        Set selMultiChildren = McOpGE(.mRgnNestedChildrenCount, 2)
            'Make those boundarys fatter and show the number of children in greenish text
        .SourceFlags = .mRgnNestedChildrenCount
        With .DisplayedObjects(selMultiChildren)
            .SetLabelText "Children: %d", _
                mcsltDisplaySourceFlags + mcsltLabelTopleft + mcsltLabelInside, &H80FF00    'greenish
            .SetBorderWidth 2 'and a bit fatter boundary
        End With '.DisplayedObjects(selMultiChildren)

            'Highlight the children of regions that have 2 or more nested children
        Dim mcobjMultiNestedChildren As McObject
        Set mcobjMultiNestedChildren = McObjectTemp(.mvRgnNestedChildIndices.ValueMcObject.SelectedValues(selMultiChildren))
            'Note the SelectedValues in the above statement returns an array of Variant's
            'The McObjectTemp function unwinds this into a form that can be used by DisplayedObjects,
            'below, as a selector for the region features to highlight.
        With .DisplayedObjects(mcobjMultiNestedChildren)
                .SetColors &HFF0000, mcdoscSetBorderColor  'show in blue
                .SetBorderWidth 2 'with fat boundary
            If .Count > 0 Then
                MsgBox "Children of regions with 2 or more nested children are shown in blue."
            Else
                MsgBox "No regions in this image's AOI have two or more nested children."
            End If
        End With '.DisplayedObjects(mcobjMultiNestedChildren)
    End With 'ActiveImage.RegionFeatures
End Sub 'LabelRegionsWithTwoOrMoreNestedChildren

'Highlight outermost regions that have multiply nested children
Public Sub HighlightRegionsWithMultiplyNestedChildren()
    If uLoadExampleImage Then Exit Sub
    If uDetectRegionsWithHoles() Then Exit Sub
    With ActiveImage.RegionFeatures
        Dim selNestedRegionsWithChildren As McObject
        Set selNestedRegionsWithChildren = McOpAND(McOpGT(.mRgnNestedChildrenCount, 0), McOpEQ(.mRgnNestingDepth, 1))
        Dim selOuterRgnWithMultiNestedChildren As Variant
        selOuterRgnWithMultiNestedChildren = .miRgnNestedWithinIndex.ValueMcObject.SelectedValues(selNestedRegionsWithChildren)
            'Highlight outermost features around regions that have children of their own
        With .DisplayedObjects(selOuterRgnWithMultiNestedChildren)
            .SetColors &HFFFF00  'cyan
            .SetBorderWidth 2 'and wider
            If .Count > 0 Then
                MsgBox "Outer regions surrounding regions that have children of their own are shown highlighted."
            Else
                MsgBox "No regions in this image's AOI have multiply nested children."
            End If
        End With
    End With 'ActiveImage.RegionFeatures
End Sub 'HighlightRegionsWithMultiplyNestedChildren

'Create an AOI with a hole in it by setting the mcofDefaultXorOnMerge AOI OptionFlags
Public Sub CreateAOIwithHoleInIt()
    Images.Open Path + "Images\BoneBig.jpg"
    With ActiveImage.Aoi
        .Reset
        Dim rectIB As SINGLERECT
        rectIB = .BoundingRect 'image bounds
        .SetBox 0, rectIB.Left, rectIB.Top, rectIB.Right, rectIB.Bottom
        .SetEllipse 1, 200, 200, 300, 200
        .OptionFlags(mcofDefaultXorOnMerge) = mcofDefaultXorOnMerge
        'The above is the key statement, as it causes regions to be XOR'ed when
        'the AOI union bit mask is formed.  This causes a nested region to
        'create a hole in its parent region.
    End With 'ActiveImage.AOI

    ActiveImage.RegionFeatures.Threshold.Execute

    MsgBox "Regions are detected only outside the inner AOI ellipse." + vbCrLf _
        + "When you press OK, the image will close."
    ActiveWindow.Close
End Sub 'CreateAOIwithHoleInIt

'Convert holes into nested regions, preserving holes in the union bit mask with
'the mcofDefaultXorOnMerge OptionFlags
Public Sub MakeHolesIntoNestedRegions()
    If uLoadExampleImage Then Exit Sub
    If uDetectRegionsWithHoles() Then Exit Sub
    With ActiveImage.RegionFeatures
        'Merge the holes into the regions as nested regions
        .Merge .Holes
        'Turn on XOR on merge (so the holes will appear in the union bit mask)
        .OptionFlags(mcofDefaultXorOnMerge) = mcofDefaultXorOnMerge
        .FillHoles 'fill in any holes so they don't mess up the XOR
        MsgBox "The holes are now nested regions." + vbCrLf + _
            "When you press OK, the union bit mask will be shown as a separate image."
        'Show the union bit mask as an image
        Dim maskImage As McImage
        Set maskImage = .CreateFeatureMask(mcfmfDisplayMaskImage + mcfmfUseAoiBoundsAsDefault)
        maskImage.DisplayName = "XOR'ed mask of regions with holes"
        maskImage.Modified = False
        MsgBox "The mask image shows the bit mask made with holes merged in" + vbCrLf + _
            "and the mcofDefaultXorOnMerge OptionFlag on." + vbCrLf + _
            "When you press OK, the image will disappear."
        ActiveWindow.Close
    End With 'ActiveImage.RegionFeatures
End Sub 'ShowAllHoles
See Also