Click or drag to resize

RegionsOperatorsmRgnIllFormed Method

Measure of the degree to which a region boundary is ill formed.

Namespace:  MediaCy.IQL.Operators
Assembly:  MediaCy.IQL.Operators (in MediaCy.IQL.Operators.dll) Version: 3.1.0.0
Syntax
VB
<ExtensionAttribute>
Public Shared Function mRgnIllFormed ( 
	regions As McRegions
) As McMeasure

Parameters

regions
Type: MediaCy.IQL.FeaturesMcRegions

Return Value

Type: McMeasure

Usage Note

In Visual Basic and C#, you can call this method as an instance method on any object of type McRegions. When you use instance method syntax to call this method, omit the first parameter. For more information, see Extension Methods (Visual Basic) or Extension Methods (C# Programming Guide).
Remarks
The mRgnIllFormed measurement is 0 (mcrifAllOK) for regions whose boundary is such that all measurements will yield correct results. It is non-zero for regions that might violate the assumptions for one or more measurements. A polygon boundary can be ill-formed for a number of reasons. A different value is assigned to the mRgnIllFormed measurement for each region depending on what type of boundary problem the region presents. Increasing values indicate more serious problems, as described below The value is set to 1 (mcrifNotConvex) for a region where the convex hull of the boundary is not identical to the boundary; that is, for any region with a "jagged" boundary. This condition alone will not lead to any erroneously computed measurement results, but it may violate assumptions in some test situations. For example, the mRgnMinRadius measurement could easily be showing the distance to an indentation on the boundary, when the experimentor was interested in only the minimum radius of the convex hull. Note that the mRgnPerimeterRatio will be less than 1 for any region where this condition exists. The value is 2 (mcrifMinorDoubleValued) for any region where the boundary is "double-valued", as seen from the interior geometric centroid, but is double-valued for only closely spaced vertices. The test is based on seeing if the vertices make a continuous sweep of monotonically increasing or decreasing angle going from the first to last vertex of the boundary. This test may find one or two-pixel sized double-valued sections caused by "jagged" boundaries. These minor double-valued transitions are common for autodetected blob boundarys, especially if no smoothing has been performed (see McThreshold.Smoothing). They are also common for user-drawn boundaries where portions of the boundary have been "sketched" by continously dragging the mouse with the left button down. The value is 3 (mcrifMajorDoubleValued) for any region where the boundary is "double-valued", as seen from the geometric centroid, on a scale of three pixels or more. This is a stronger version of the test for mcrifMinorDoubleValued (2), above. This test will find seriously double-valued boundaries, ignoring one or two-pixel-sized "double-valued" elements which might be caused by "noise" in an otherwise smooth region boundary. The mRgnIllFormed value is 4 (mcrifZeroArea) for any region where the boundary polygon has any section with zero interior area. Assuming that the mcofOutlinePixelTiles bit of the OptionFlags is clear, this situation will be the case for all autodetected regions that are one-pixel sized or consist of a single line. Also any autodetected region with one-pixel wide tendrils has zero area in the boundary polygon tracing these tendrils (thus, any region with a non-zero mRgnNumDendrites measurement is ill-formed in this respect). Pixel-based measurements such as mRgnArea will still be correct for regions where the mRgnIllFormed is 4 or less. Those measurements which are pixel-based are noted in the documentation, and their McMeasure.Attributes(mcmaidCategories) property will have the mcmcfHistogram flag set. Except for some very unusual cases, boundaries with zero area sections are also double-valued as seen from the centroid. The value is 5 (mcrifCentroidOutside) for any region where the geometric centroid falls on or outside of the boundary polygon. Since the boundary will generally also be double-valued in this case, this value also implies mcrifMajorDoubleValued (3). The boundary may or may not also have sections with zero area. For regions with mRgnIllFormed values of mcrifMinorDoubleValued, mcrifMajorDoubleValued, mcrifZeroArea or mcrifCentroidOutside (2, 3, 4 or 5) radius and diameter measurements are ambiguous (since there are two or more radial values at some angles). For mRgnIllFormed values of mcrifCentroidOutside (5) or less, all other measurements are accurate, but may be suspect for any given measurement task. For example, the mRgnPolygonialArea geometric area of a region with tendrils (a mRgnIllFormed value of mcrifZeroArea) will reflect zero area contributed from the tendrils (because the tendril "border" retraces itself exactly), which is mathematically correct, but probably not what is of interest to the user (in this case, mRgnArea, the pixel counted area, is probably of more use). A final test is performed to detect self-crossing (e.g., figure-8) region feature boundaries drawn by the user or set by a call to McFeatures.SetFeaturePoints (McRegions features of Type mcftScanList, i.e. those created by the McThreshold.Execute method or McFeatures.SetFromMask method, will never have a self-crossing boundary polygon). Regions with self-crossing region boundaries are given a mRgnIllFormed value of 6 (mcrifSelfCrossing). Virtually all measurements based on the boundary polygon (except for mRgnPerimeter and the caliper measures) are invalid for any region with a self-crossing boundary.
Examples
VB
'**** MeasuresWithMcRegionsResults.bas ****

Option Explicit

'Note: the BoneBig.jpg example image is a good one for these examples
Private Function uLoadExampleImage(Optional strImage As String = "BoneBig.jpg") As Boolean
    If MsgBox("Open example image?", vbYesNo) = vbYes Then
        Images.Open Path + "Images\" + strImage
        ActiveWindow.Position = Array(5, 5)
    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
    uLoadExampleImage = ActiveImage Is Nothing
End Function 'uLoadExampleImage


'Utility sub to remove any existing features
Public Sub ResetAllStandardFeatures()
    If ActiveImage Is Nothing Then Exit Sub
    With ActiveImage
        .PointFeatures.Reset
        .LineFeatures.Reset
        .RegionFeatures.Reset
    End With 'ActiveImage
End Sub 'ResetAllStandardFeatures

'Remove region features touching the AOI and ones with area smaller than 25 square pixels
Private Sub FindLargeNonTouchingRegions()
    ResetAllStandardFeatures 'remove any existing features
    If uLoadExampleImage Then Exit Sub
    ActiveWindow.View.Magnification = 2
    With ActiveImage
        .Aoi.SetBox -1, 0, 0, 250, 250
        .RegionFeatures.Threshold.Execute
        .RegionFeatures.CleanUpBordersAndNoise .Aoi, mcrbAllBorders, 25
    End With 'ActiveImage
End Sub 'FindLargeNonTouchingRegions

'The ShowConvexHull example shows the convex hull superimposed on region boundaries
Public Sub ShowConvexHull()
    FindLargeNonTouchingRegions
    Dim mcregionsConvexHull As McRegions
    Set mcregionsConvexHull = ActiveImage.RegionFeatures.mrRgnConvexHullAsRegions.Value
    With mcregionsConvexHull
        .AutoDisplay = True
        .DisplayedObjects.SetColors &HFFFF& 'show convex hull as yellow
    End With 'mcregionsConvexHull
    MsgBox McCStr("Convex Hulls show in Yellow.\n They will disappear when you press OK.")
    mcregionsConvexHull.AutoDisplay = False
End Sub 'ShowConvexHull

'The ShowEquivalentEllipse example shows the convex hull superimposed on region boundaries
Public Sub ShowEquivalentEllipse()
    FindLargeNonTouchingRegions
    Dim mcregionsEquivEllipse As McRegions
    Set mcregionsEquivEllipse = ActiveImage.RegionFeatures.mrRgnEquivEllipseAsRegions.Value
    With mcregionsEquivEllipse
        .AutoDisplay = True
        .DisplayedObjects.SetColors &HFFFF00  'show equivalent ellipse as cyan
    End With 'mcregionsEquivEllipse
    MsgBox McCStr("Equivalent Ellipses show in Cyan.\n They will disappear when you press OK.")
    mcregionsEquivEllipse.AutoDisplay = False
End Sub 'ShowEquivalentEllipse

'The ShowEllipseOrHull example shows the Equivalent Ellipse on boundaries that
'are not double-valued (as see from the centroid), and it shows the
'Convex Hull on those that are.
'
Public Sub ShowEllipseOrHull()
    FindLargeNonTouchingRegions
        'Find a selector for only ill-formed boundaries
    Dim SelectIllFormed() As Long
    SelectIllFormed = McOpGE(ActiveImage.RegionFeatures.mRgnIllFormed, mcrifMajorDoubleValued)

        'For boundaries that are NOT ill-formed, we show the equivalent ellipse
    Dim mcregionsEquivEllipse As McRegions
    Set mcregionsEquivEllipse = ActiveImage.RegionFeatures.mrRgnEquivEllipseAsRegions.Value
    With mcregionsEquivEllipse
        .AutoDisplay = True
            'Set the equivalent ellipse for all ill-formed boundaries to non-Visible
        .DisplayedObjects(SelectIllFormed).SetStyle mcgsVisible, mcgsNoBits
        .DisplayedObjects.SetColors &HFFFF00  'show equivalent ellipse as cyan
    End With 'mcregionsEquivEllipse

        'For boundaries that ARE ill-formed, we show the Convex Hull
    Dim mcregionsConvexHull As McRegions
    Set mcregionsConvexHull = ActiveImage.RegionFeatures.mrRgnConvexHullAsRegions.Value
    With mcregionsConvexHull
        .AutoDisplay = True
            'Set the convex hull for all not ill-formed boundaries to non-Visible
        .DisplayedObjects(McOpNOT(SelectIllFormed)).SetStyle mcgsVisible, mcgsNoBits
        .DisplayedObjects.SetColors &HFFFF& 'show convex hull as yellow
    End With 'mcregionsConvexHull

    MsgBox McCStr("Equivalent Ellipses show in Cyan on single-valued bounds.\nConvex Hulls show in Yellow on double-valued bounds.\nThey will disappear when you press OK.")
        'Note: above McCStr turns \n into vbLf (i.e. a newline)
    mcregionsEquivEllipse.AutoDisplay = False
    mcregionsConvexHull.AutoDisplay = False
End Sub 'ShowEllipseOrHull


'The ShowBest-fit features example shows how to create best-fit features Line, Circle, Arc
Public Sub ShowBestFitFeatures()
    ResetAllStandardFeatures 'remove any existing features
    If uLoadExampleImage Then Exit Sub
    With ActiveImage
        .RegionFeatures.Threshold.Execute
    End With 'ActiveImage

    Dim myPoints As McPoints
    Set myPoints = ActiveImage.RegionFeatures.mpRgnCentroidAsPoint.Value
    myPoints.AutoDisplay = True

    'create best-fit line
    Dim BestFitLine As McLines
    Set BestFitLine = myPoints.mlPtBestFitLineAsLine.Value
    BestFitLine.AutoDisplay = True

    'create best-fit circle
    Dim BestFitCircle As McRegions
    Set BestFitCircle = myPoints.mrPtBestFitCircleAsRegion.Value
    BestFitCircle.AutoDisplay = True

    'create best-fit arc
    Dim BestFitArc As McLines
    Set BestFitArc = myPoints.mlPtBestFitArcAsLine.Value
    BestFitArc.AutoDisplay = True
    BestFitArc.DisplayedObjects.SetColors &HFFFF& 'show arc as yellow
End Sub 'ShowBestFitFeatures

'This example demonstrates usng of mlRefMinDistanceAsLine and mlRefMinDistance measurements
Public Sub RegionMinDistancesToPointAndLine()
    If uLoadExampleImage Then Exit Sub
    ActiveWindow.View.Magnification = 2

    With ActiveImage
        .RegionFeatures.Threshold.AutoFindPhase = mcfpBrightest
        .RegionFeatures.Threshold.Execute
        .RegionFeatures.CleanUpBordersAndNoise , mcrbNoBorder, 500 'get rid of small regions

            'Create a single reference point feature
        .PointFeatures.SetFeaturePoints -1, Array(240, 220) 'put a reference point on the image
        .PointFeatures.DisplayedObjects.SetColors &HFFFF00  'make it cyan
        .PointFeatures.DisplayedObjects.SetPointShape mcgpsLargeTarget90 'and bigger
        .PointFeatures.DisplayedObjects.SetPointScalePercent 200 'and even bigger yet
        .PointFeatures.DisplayedObjects.SetBorderWidth 2 'and fatter

        Dim myRegionToPointRef As McRefFeatures
        Set myRegionToPointRef = ActiveImage.RegionFeatures.Reference.Duplicate
        Set myRegionToPointRef.ReferenceFeature = ActiveImage.PointFeatures
        Dim mclinesRefToPoint As McLines
        Set mclinesRefToPoint = myRegionToPointRef.mlRefMinDistanceAsLine.Value
        mclinesRefToPoint.AutoDisplay = True
        mclinesRefToPoint.DisplayedObjects.SetLineEnding mcgweEnd, mcgleNothing 'no ending arrow
        mclinesRefToPoint.DisplayedObjects.SetColors &HFFFF&

            'Create a single reference line feature
        .LineFeatures.Reset
        .LineFeatures.SetFeaturePoints 0, Array(10, 150, 200, 10)
        .LineFeatures.DisplayedObjects.SetColors &HFF00FF  'make it magenta
        .LineFeatures.DisplayedObjects.SetBorderWidth 2 'and fatter

        Dim myRegionToLineRef As McRefFeatures
        Set myRegionToLineRef = ActiveImage.RegionFeatures.Reference.Duplicate
        Set myRegionToLineRef.ReferenceFeature = ActiveImage.LineFeatures
        Dim mclinesRefToLine As McLines
        Set mclinesRefToLine = myRegionToLineRef.mlRefMinDistanceAsLine.Value
        mclinesRefToLine.AutoDisplay = True
        mclinesRefToLine.DisplayedObjects.SetLineEnding mcgweEnd, mcgleNothing 'no ending arrow
        mclinesRefToLine.DisplayedObjects.SetColors &HFF00&

            'Create a single region feature
        Dim mRegions As McRegions
        Set mRegions = .RegionFeatures.Duplicate

        mRegions.Reset
        mRegions.AutoDisplay = True
        mRegions.SetFeaturePoints 0, Array(100, 100, 200, 100, 200, 200, 100, 200)
        mRegions.DisplayedObjects.SetColors &HFF80FF  'make it magenta
        mRegions.DisplayedObjects.SetBorderWidth 2 'and fatter

        Dim myRegionToRegionRef As McRefFeatures
        Set myRegionToRegionRef = ActiveImage.RegionFeatures.Reference.Duplicate
        Set myRegionToRegionRef.ReferenceFeature = mRegions
        Dim mclinesRefToRegion As McLines
        Set mclinesRefToRegion = myRegionToRegionRef.mlRefMinDistanceAsLine.Value
        mclinesRefToRegion.AutoDisplay = True
        mclinesRefToRegion.DisplayedObjects.SetLineEnding mcgweEnd, mcgleNothing 'no ending arrow
        mclinesRefToRegion.DisplayedObjects.SetColors &HFF0000

        Output.PrintMessage "There are" + Str(.RegionFeatures.Count) + " large region features." + vbCrLf + _
            "Min Distance from regions to ref point = " & _
            McToText(myRegionToPointRef.mRefMinDistance) & vbCrLf & _
            "Min Distance from regions to ref line = " & _
            McToText(myRegionToLineRef.mRefMinDistance) & vbCrLf & _
            "Min Distance from regions to ref region = " & _
            McToText(myRegionToRegionRef.mRefMinDistance)

        MsgBox "Min distance from regions to reference point show in yellow." + vbCrLf + _
            "Min distance from regions to reference line show in green." + vbCrLf + _
            "Min distance from regions to reference region show in blue." + vbCrLf + _
            "When you press OK, they will disappear."

    End With 'Active Image
End Sub 'RegionMinDistancesToPointAndLine

'This example demonstrates usng of mlRefMaxDistanceAsLine and mlRefMaxDistance measurements
Public Sub RegionMaxDistancesToPointAndLine()
    If uLoadExampleImage Then Exit Sub
    ActiveWindow.View.Magnification = 2

    With ActiveImage
        .RegionFeatures.Threshold.AutoFindPhase = mcfpBrightest
        .RegionFeatures.Threshold.Execute
        .RegionFeatures.CleanUpBordersAndNoise , mcrbNoBorder, 500 'get rid of small regions

            'Create a single reference point feature
        .PointFeatures.SetFeaturePoints -1, Array(240, 220) 'put a reference point on the image
        .PointFeatures.DisplayedObjects.SetColors &HFFFF00  'make it cyan
        .PointFeatures.DisplayedObjects.SetPointShape mcgpsLargeTarget90 'and bigger
        .PointFeatures.DisplayedObjects.SetPointScalePercent 200 'and even bigger yet
        .PointFeatures.DisplayedObjects.SetBorderWidth 2 'and fatter

        Dim myRegionToPointRef As McRefFeatures
        Set myRegionToPointRef = ActiveImage.RegionFeatures.Reference.Duplicate
        Set myRegionToPointRef.ReferenceFeature = ActiveImage.PointFeatures
        Dim mclinesRefToPoint As McLines
        Set mclinesRefToPoint = myRegionToPointRef.mlRefMaxDistanceAsLine.Value
        mclinesRefToPoint.AutoDisplay = True
        mclinesRefToPoint.DisplayedObjects.SetLineEnding mcgweEnd, mcgleNothing 'no ending arrow
        mclinesRefToPoint.DisplayedObjects.SetColors &HFFFF&

            'Create a single reference line feature
        .LineFeatures.Reset
        .LineFeatures.SetFeaturePoints 0, Array(10, 150, 200, 10)
        .LineFeatures.DisplayedObjects.SetColors &HFF00FF  'make it magenta
        .LineFeatures.DisplayedObjects.SetBorderWidth 2 'and fatter

        Dim myRegionToLineRef As McRefFeatures
        Set myRegionToLineRef = ActiveImage.RegionFeatures.Reference.Duplicate
        Set myRegionToLineRef.ReferenceFeature = ActiveImage.LineFeatures
        Dim mclinesRefToLine As McLines
        Set mclinesRefToLine = myRegionToLineRef.mlRefMaxDistanceAsLine.Value
        mclinesRefToLine.AutoDisplay = True
        mclinesRefToLine.DisplayedObjects.SetLineEnding mcgweEnd, mcgleNothing 'no ending arrow
        mclinesRefToLine.DisplayedObjects.SetColors &HFF00&

            'Create a single region feature
        Dim mRegions As McRegions
        Set mRegions = .RegionFeatures.Duplicate

        mRegions.Reset
        mRegions.AutoDisplay = True
        mRegions.SetFeaturePoints 0, Array(100, 100, 200, 100, 200, 200, 100, 200)
        mRegions.DisplayedObjects.SetColors &HFF80FF  'make it magenta
        mRegions.DisplayedObjects.SetBorderWidth 2 'and fatter

        Dim myRegionToRegionRef As McRefFeatures
        Set myRegionToRegionRef = ActiveImage.RegionFeatures.Reference.Duplicate
        Set myRegionToRegionRef.ReferenceFeature = mRegions
        Dim mclinesRefToRegion As McLines
        Set mclinesRefToRegion = myRegionToRegionRef.mlRefMaxDistanceAsLine.Value
        mclinesRefToRegion.AutoDisplay = True
        mclinesRefToRegion.DisplayedObjects.SetLineEnding mcgweEnd, mcgleNothing 'no ending arrow
        mclinesRefToRegion.DisplayedObjects.SetColors &HFF0000

        Output.PrintMessage "There are" + Str(.RegionFeatures.Count) + " large region features." + vbCrLf + _
            "Max Distance from regions to ref point = " & _
            McToText(myRegionToPointRef.mRefMaxDistance) & vbCrLf & _
            "Max Distance from regions to ref line = " & _
            McToText(myRegionToLineRef.mRefMaxDistance) & vbCrLf & _
            "Max Distance from regions to ref region = " & _
            McToText(myRegionToRegionRef.mRefMaxDistance)

        MsgBox "Max distance from regions to reference point show in yellow." + vbCrLf + _
            "Max distance from regions to reference line show in green." + vbCrLf + _
            "Max distance from regions to reference region show in blue." + vbCrLf + _
            "When you press OK, they will disappear."
    End With 'Active Image
End Sub 'RegionMaxDistancesToPointAndLine

'This example demonstrates usng of mlRefMaxDistanceAsLine and mlRefMaxDistance measurements
Public Sub RegionPerpendicularDistancesToLine()
    If uLoadExampleImage Then Exit Sub

    With ActiveImage
        .RegionFeatures.Threshold.AutoFindPhase = mcfpBrightest
        .RegionFeatures.Threshold.Execute
        .RegionFeatures.CleanUpBordersAndNoise , mcrbNoBorder, 500 'get rid of small regions

            'Create a single reference line feature
        .LineFeatures.Reset
        .LineFeatures.SetFeaturePoints 0, Array(10, 150, 100, 80)
        .LineFeatures.DisplayedObjects.SetColors &HFF00FF  'make it magenta
        .LineFeatures.DisplayedObjects.SetBorderWidth 2 'and fatter

        Dim myRegionToLineRef As McRefFeatures
        Set myRegionToLineRef = ActiveImage.RegionFeatures.Reference.Duplicate
        Set myRegionToLineRef.ReferenceFeature = ActiveImage.LineFeatures
        Dim mclinesRefToLine As McLines
        Set mclinesRefToLine = myRegionToLineRef.mlRefPerpDistanceAsLine.Value
        mclinesRefToLine.AutoDisplay = True
        mclinesRefToLine.DisplayedObjects.SetLineEnding mcgweEnd, mcgleNothing 'no ending arrow
        mclinesRefToLine.DisplayedObjects.SetColors &HFF00&

        Dim myPoints As McPoints
        Set myPoints = ActiveImage.RegionFeatures.mpRgnCentroidAsPoint.Value.Duplicate
        myPoints.AutoDisplay = True
        Set myPoints.Reference.ReferenceFeature = ActiveImage.LineFeatures
        Dim mclinesPRefToLine As McLines
        Set mclinesPRefToLine = myPoints.Reference.mlRefPerpDistanceAsLine.Value
        mclinesPRefToLine.AutoDisplay = True
        mclinesPRefToLine.DisplayedObjects.SetLineEnding mcgweEnd, mcgleNothing 'no ending arrow
        mclinesPRefToLine.DisplayedObjects.SetColors &HFF0000

        Output.PrintMessage "There are" + Str(.RegionFeatures.Count) + " large region features." + vbCrLf + _
            "Perpendicular Distance from regions to ref line = " & _
            McToText(myRegionToLineRef.mRefPerpDistance) + vbCrLf + _
            "Perpendicular Distance from points to ref line = " & _
            McToText(myPoints.Reference.mRefPerpDistance)

        MsgBox "Perpendicular distance from regions to reference line show in green." + vbCrLf + _
            "Perpendicular distance from points to reference line show in blue." + vbCrLf + _
            "When you press OK, they will disappear."
    End With 'Active Image
End Sub 'RegionPerpendicularDistancesToLine

'gap measurements example
Sub LinesGapMeasurements()
    If uLoadExampleImage("Tumor.tif") Then Exit Sub

    ActiveImage.LineFeatures.Reset
    '******* test line
    ReDim temp_fPts(0 To 13)
    temp_fPts(0).x = 3.21637: temp_fPts(0).y = 562.865
    temp_fPts(1).x = 62.7193: temp_fPts(1).y = 525.877
    temp_fPts(2).x = 141.52: temp_fPts(2).y = 495.322
    temp_fPts(3).x = 215.497: temp_fPts(3).y = 453.509
    temp_fPts(4).x = 258.918: temp_fPts(4).y = 443.86
    temp_fPts(5).x = 334.503: temp_fPts(5).y = 437.427
    temp_fPts(6).x = 400.439: temp_fPts(6).y = 437.427
    temp_fPts(7).x = 434.211: temp_fPts(7).y = 469.591
    temp_fPts(8).x = 471.199: temp_fPts(8).y = 480.848
    temp_fPts(9).x = 498.538: temp_fPts(9).y = 496.93
    temp_fPts(10).x = 524.269: temp_fPts(10).y = 524.269
    temp_fPts(11).x = 595.029: temp_fPts(11).y = 546.784
    temp_fPts(12).x = 659.357: temp_fPts(12).y = 575.731
    temp_fPts(13).x = 705.994: temp_fPts(13).y = 606.287

    ActiveImage.LineFeatures.SetFeaturePoints 0, temp_fPts
    ActiveImage.LineFeatures.DisplayedObjects.SetColors &HFF00&
    ActiveImage.LineFeatures.DisplayedObjects.SetBorderWidth 2 'and fatter

    'reference line
    ReDim temp_fPts(0 To 17)
    temp_fPts(0).x = 6.43275: temp_fPts(0).y = 384.357
    temp_fPts(1).x = 30.5556: temp_fPts(1).y = 382.749
    temp_fPts(2).x = 59.5029: temp_fPts(2).y = 376.316
    temp_fPts(3).x = 80.4094: temp_fPts(3).y = 376.316
    temp_fPts(4).x = 99.7076: temp_fPts(4).y = 366.667
    temp_fPts(5).x = 110.965: temp_fPts(5).y = 357.018
    temp_fPts(6).x = 159.211: temp_fPts(6).y = 334.503
    temp_fPts(7).x = 197.807: temp_fPts(7).y = 316.813
    temp_fPts(8).x = 258.918: temp_fPts(8).y = 315.205
    temp_fPts(9).x = 316.813: temp_fPts(9).y = 315.205
    temp_fPts(10).x = 374.708: temp_fPts(10).y = 329.678
    temp_fPts(11).x = 413.304: temp_fPts(11).y = 336.111
    temp_fPts(12).x = 463.158: temp_fPts(12).y = 355.409
    temp_fPts(13).x = 540.351: temp_fPts(13).y = 387.573
    temp_fPts(14).x = 572.515: temp_fPts(14).y = 424.561
    temp_fPts(15).x = 620.76: temp_fPts(15).y = 422.953
    temp_fPts(16).x = 657.749: temp_fPts(16).y = 466.374
    temp_fPts(17).x = 696.345: temp_fPts(17).y = 479.24

    Dim myRefLine As McLines
    Set myRefLine = ActiveImage.LineFeatures.Duplicate
    myRefLine.SetFeaturePoints 0, temp_fPts
    myRefLine.AutoDisplay = True
    myRefLine.DisplayedObjects.SetColors &HFFFF00
    myRefLine.DisplayedObjects.SetBorderWidth 2 'and fatter

    Dim myGapToLineRef As McRefFeatures
    Set myGapToLineRef = ActiveImage.LineFeatures.Reference.Duplicate
    Set myGapToLineRef.ReferenceFeature = myRefLine
    Dim minLines As McLines
    Set minLines = myGapToLineRef.mlRefMinGapAsLine.Value
    minLines.AutoDisplay = True
    minLines.DisplayedObjects.SetColors &HFF0000   'make it magenta
    minLines.DisplayedObjects.SetBorderWidth 2 'and fatter

    Dim maxLines As McLines
    Set maxLines = myGapToLineRef.mlRefMaxGapAsLine.Value
    maxLines.AutoDisplay = True
    maxLines.DisplayedObjects.SetColors &HFF00FF   'make it green
    maxLines.DisplayedObjects.SetBorderWidth 2 'and fatter

    Dim meanLines As McLines
    Set meanLines = myGapToLineRef.mlRefMeanGapAsLine.Value
    meanLines.AutoDisplay = True
    meanLines.DisplayedObjects.SetColors &H0     'make it black
    meanLines.DisplayedObjects.SetBorderWidth 2 'and fatter

    Output.PrintMessage "There are" + Str(ActiveImage.LineFeatures.Count) + " line features." + vbCrLf + _
        "Minimum gap to ref line = " & _
        McToText(myGapToLineRef.mRefMinGap.Value) + vbCrLf + _
        "Maximum gap to ref line = " & _
        McToText(myGapToLineRef.mRefMaxGap.Value) + vbCrLf + _
        "Average gap to ref line = " & _
        McToText(myGapToLineRef.mRefMeanGap.Value)

    MsgBox "Gap distances between lines are show." + vbCrLf + _
        "Min distance is blue, Max is pink, Mean is black" & vbCrLf + _
        "When you press OK, they will disappear."
End Sub

'vertical gap measurements example
Sub LinesVerticalGapMeasurements()
    If uLoadExampleImage("Tumor.tif") Then Exit Sub

    ActiveImage.LineFeatures.Reset
    '******* test line
    ReDim temp_fPts(0 To 13)
    temp_fPts(0).x = 3.21637: temp_fPts(0).y = 562.865
    temp_fPts(1).x = 62.7193: temp_fPts(1).y = 525.877
    temp_fPts(2).x = 141.52: temp_fPts(2).y = 495.322
    temp_fPts(3).x = 215.497: temp_fPts(3).y = 453.509
    temp_fPts(4).x = 258.918: temp_fPts(4).y = 443.86
    temp_fPts(5).x = 334.503: temp_fPts(5).y = 437.427
    temp_fPts(6).x = 400.439: temp_fPts(6).y = 437.427
    temp_fPts(7).x = 434.211: temp_fPts(7).y = 469.591
    temp_fPts(8).x = 471.199: temp_fPts(8).y = 480.848
    temp_fPts(9).x = 498.538: temp_fPts(9).y = 496.93
    temp_fPts(10).x = 524.269: temp_fPts(10).y = 524.269
    temp_fPts(11).x = 595.029: temp_fPts(11).y = 546.784
    temp_fPts(12).x = 659.357: temp_fPts(12).y = 575.731
    temp_fPts(13).x = 705.994: temp_fPts(13).y = 606.287

    ActiveImage.LineFeatures.SetFeaturePoints 0, temp_fPts
    ActiveImage.LineFeatures.DisplayedObjects.SetColors &HFF00&
    ActiveImage.LineFeatures.DisplayedObjects.SetBorderWidth 2 'and fatter

    'reference line
    ReDim temp_fPts(0 To 17)
    temp_fPts(0).x = 6.43275: temp_fPts(0).y = 384.357
    temp_fPts(1).x = 30.5556: temp_fPts(1).y = 382.749
    temp_fPts(2).x = 59.5029: temp_fPts(2).y = 376.316
    temp_fPts(3).x = 80.4094: temp_fPts(3).y = 376.316
    temp_fPts(4).x = 99.7076: temp_fPts(4).y = 366.667
    temp_fPts(5).x = 110.965: temp_fPts(5).y = 357.018
    temp_fPts(6).x = 159.211: temp_fPts(6).y = 334.503
    temp_fPts(7).x = 197.807: temp_fPts(7).y = 316.813
    temp_fPts(8).x = 258.918: temp_fPts(8).y = 315.205
    temp_fPts(9).x = 316.813: temp_fPts(9).y = 315.205
    temp_fPts(10).x = 374.708: temp_fPts(10).y = 329.678
    temp_fPts(11).x = 413.304: temp_fPts(11).y = 336.111
    temp_fPts(12).x = 463.158: temp_fPts(12).y = 355.409
    temp_fPts(13).x = 540.351: temp_fPts(13).y = 387.573
    temp_fPts(14).x = 572.515: temp_fPts(14).y = 424.561
    temp_fPts(15).x = 620.76: temp_fPts(15).y = 422.953
    temp_fPts(16).x = 657.749: temp_fPts(16).y = 466.374
    temp_fPts(17).x = 696.345: temp_fPts(17).y = 479.24

    Dim myRefLine As McLines
    Set myRefLine = ActiveImage.LineFeatures.Duplicate
    myRefLine.SetFeaturePoints 0, temp_fPts
    myRefLine.AutoDisplay = True
    myRefLine.DisplayedObjects.SetColors &HFFFF00
    myRefLine.DisplayedObjects.SetBorderWidth 2 'and fatter

    Dim myGapToLineRef As McRefFeatures
    Set myGapToLineRef = ActiveImage.LineFeatures.Reference.Duplicate
    Set myGapToLineRef.ReferenceFeature = myRefLine
    Dim minLines As McLines
    Set minLines = myGapToLineRef.mlRefMinGapVAsLine.Value
    minLines.AutoDisplay = True
    minLines.DisplayedObjects.SetColors &HFF0000   'make it magenta
    minLines.DisplayedObjects.SetBorderWidth 2 'and fatter

    Dim maxLines As McLines
    Set maxLines = myGapToLineRef.mlRefMaxGapVAsLine.Value
    maxLines.AutoDisplay = True
    maxLines.DisplayedObjects.SetColors &HFF00FF   'make it green
    maxLines.DisplayedObjects.SetBorderWidth 2 'and fatter

    Dim meanLines As McLines
    Set meanLines = myGapToLineRef.mlRefMeanGapVAsLine.Value
    meanLines.AutoDisplay = True
    meanLines.DisplayedObjects.SetColors &H0     'make it black
    meanLines.DisplayedObjects.SetBorderWidth 2 'and fatter

    Output.PrintMessage "There are" + Str(ActiveImage.LineFeatures.Count) + " line features." + vbCrLf + _
        "Minimum vertical gap to ref line = " & _
        McToText(myGapToLineRef.mRefMinGapV.Value) + vbCrLf + _
        "Maximum vertical gap to ref line = " & _
        McToText(myGapToLineRef.mRefMaxGapV.Value) + vbCrLf + _
        "Average vertical gap to ref line = " & _
        McToText(myGapToLineRef.mRefMeanGapV.Value)

    MsgBox "Vertical Gap distances between lines are show." + vbCrLf + _
        "Min distance is blue, Max is pink, Mean is black" & vbCrLf + _
        "When you press OK, they will disappear."
End Sub

'horizontal gap measurements examples
Sub LinesHorizontalGapMeasurements()
    If uLoadExampleImage("SCR1.TIF") Then Exit Sub

    ActiveImage.LineFeatures.Reset
    '******* test line
    ReDim temp_fPts(0 To 6)
    temp_fPts(0).x = 252#: temp_fPts(0).y = 59#
    temp_fPts(1).x = 253#: temp_fPts(1).y = 93#
    temp_fPts(2).x = 252#: temp_fPts(2).y = 159#
    temp_fPts(3).x = 246#: temp_fPts(3).y = 211#
    temp_fPts(4).x = 240#: temp_fPts(4).y = 258#
    temp_fPts(5).x = 237#: temp_fPts(5).y = 305#
    temp_fPts(6).x = 235#: temp_fPts(6).y = 356#

    ActiveImage.LineFeatures.SetFeaturePoints 0, temp_fPts
    ActiveImage.LineFeatures.DisplayedObjects.SetColors &HFF00&
    ActiveImage.LineFeatures.DisplayedObjects.SetBorderWidth 2 'and fatter

    'reference line
    ReDim temp_fPts(0 To 7)
    temp_fPts(0).x = 297#: temp_fPts(0).y = 19#
    temp_fPts(1).x = 295#: temp_fPts(1).y = 65#
    temp_fPts(2).x = 296#: temp_fPts(2).y = 120#
    temp_fPts(3).x = 295#: temp_fPts(3).y = 161#
    temp_fPts(4).x = 283#: temp_fPts(4).y = 224#
    temp_fPts(5).x = 281#: temp_fPts(5).y = 272#
    temp_fPts(6).x = 277#: temp_fPts(6).y = 323#
    temp_fPts(7).x = 275#: temp_fPts(7).y = 382#

    Dim myRefLine As McLines
    Set myRefLine = ActiveImage.LineFeatures.Duplicate
    myRefLine.SetFeaturePoints 0, temp_fPts
    myRefLine.AutoDisplay = True
    myRefLine.DisplayedObjects.SetColors &HFFFF00
    myRefLine.DisplayedObjects.SetBorderWidth 2 'and fatter

    Dim myGapToLineRef As McRefFeatures
    Set myGapToLineRef = ActiveImage.LineFeatures.Reference.Duplicate
    Set myGapToLineRef.ReferenceFeature = myRefLine
    Dim minLines As McLines
    Set minLines = myGapToLineRef.mlRefMinGapHAsLine.Value
    minLines.AutoDisplay = True
    minLines.DisplayedObjects.SetColors &HFF0000   'make it magenta
    minLines.DisplayedObjects.SetBorderWidth 2 'and fatter

    Dim maxLines As McLines
    Set maxLines = myGapToLineRef.mlRefMaxGapHAsLine.Value
    maxLines.AutoDisplay = True
    maxLines.DisplayedObjects.SetColors &HFF00FF   'make it green
    maxLines.DisplayedObjects.SetBorderWidth 2 'and fatter

    Dim meanLines As McLines
    Set meanLines = myGapToLineRef.mlRefMeanGapHAsLine.Value
    meanLines.AutoDisplay = True
    meanLines.DisplayedObjects.SetColors &H0     'make it black
    meanLines.DisplayedObjects.SetBorderWidth 2 'and fatter

    Output.PrintMessage "There are" + Str(ActiveImage.LineFeatures.Count) + " line features." + vbCrLf + _
        "Minimum horizontal gap to ref line = " & _
        McToText(myGapToLineRef.mRefMinGapH.Value) + vbCrLf + _
        "Maximum horizontal gap to ref line = " & _
        McToText(myGapToLineRef.mRefMaxGapH.Value) + vbCrLf + _
        "Average horizontal gap to ref line = " & _
        McToText(myGapToLineRef.mRefMeanGapH.Value)

    MsgBox "Horizontal gap distances between lines are show." + vbCrLf + _
        "Min distance is blue, Max is pink, Mean is black" & vbCrLf + _
        "When you press OK, they will disappear."
End Sub

'The ShowBestFitFeaturesWithOutliersFiltering example shows how to create
'best-fit features Circle with Outliers Filtering
Public Sub ShowBestFitFeaturesWithOutliersFiltering()
    ResetAllStandardFeatures 'remove any existing features
    If uLoadExampleImage("GEAR2.TIF") Then Exit Sub

    Dim myPoints As McPoints
    Set myPoints = ActiveImage.PointFeatures
    myPoints.AutoDisplay = True
    'add points
    ReDim temp_fPts(0 To 19)
    temp_fPts(0).x = 546.667: temp_fPts(0).y = 252.222
    temp_fPts(1).x = 497.778: temp_fPts(1).y = 150#
    temp_fPts(2).x = 400#: temp_fPts(2).y = 98.8889
    temp_fPts(3).x = 261.111: temp_fPts(3).y = 142.222
    temp_fPts(4).x = 213.333: temp_fPts(4).y = 223.333
    temp_fPts(5).x = 228.889: temp_fPts(5).y = 347.778
    temp_fPts(6).x = 303.333: temp_fPts(6).y = 421.111
    temp_fPts(7).x = 441.111: temp_fPts(7).y = 427.778
    temp_fPts(8).x = 523.333: temp_fPts(8).y = 354.444
    temp_fPts(9).x = 598.889: temp_fPts(9).y = 297.778
    temp_fPts(10).x = 585.556: temp_fPts(10).y = 176.667
    temp_fPts(11).x = 443.333: temp_fPts(11).y = 163.333
    temp_fPts(12).x = 316.667: temp_fPts(12).y = 80#
    temp_fPts(13).x = 503.333: temp_fPts(13).y = 107.778
    temp_fPts(14).x = 241.111: temp_fPts(14).y = 494.444
    temp_fPts(15).x = 176.667: temp_fPts(15).y = 324.444
    temp_fPts(16).x = 451.111: temp_fPts(16).y = 520#
    temp_fPts(17).x = 706.667: temp_fPts(17).y = 526.667
    temp_fPts(18).x = 511.111: temp_fPts(18).y = 398.889
    temp_fPts(19).x = 567.778: temp_fPts(19).y = 368.889

    myPoints.SetFeaturePoints -1, temp_fPts

    'create best-fit circle
    Dim BestFitCircle As McRegions
    myPoints.mrPtBestFitCircleAsRegion.OutliersFraction = 0
    Set BestFitCircle = myPoints.mrPtBestFitCircleAsRegion.Value.Duplicate
    BestFitCircle.AutoDisplay = True
    BestFitCircle.DisplayedObjects.SetColors &HFF0000   'make it magenta
    BestFitCircle.DisplayedObjects.SetBorderWidth 2 'and fatter

    Dim Cx As Double, Cy As Double, MajAx As Double, MinAx As Double, MajAngle As Double
    BestFitCircle.GetEllipse 0, Cx, Cy, MajAx, MinAx, MajAngle

    Dim BestFitCircle2 As McRegions
    'set 50% as outliers
    myPoints.mrPtBestFitCircleAsRegion.OutliersFraction = 0.6
    Set BestFitCircle2 = myPoints.mrPtBestFitCircleAsRegion.Value
    BestFitCircle2.AutoDisplay = True
    BestFitCircle2.DisplayedObjects.SetColors &HFF00&   'make it green
    BestFitCircle2.DisplayedObjects.SetBorderWidth 2 'and fatter

    MsgBox "Blue best-fit circle is created based on all points" & vbCrLf & _
    "Green best-fit circle is created discarding 60% of outliers"
End Sub 'ShowBestFitFeatures

'demonstrate using OutliersFraction property creating
'best-fit line
Public Sub ShowBestFitLinesWithOutliersFiltering()
    ResetAllStandardFeatures 'remove any existing features
    If uLoadExampleImage("BRACKET.TIF") Then Exit Sub

    Dim myPoints As McPoints
    Set myPoints = ActiveImage.PointFeatures
    myPoints.AutoDisplay = True
    'add points
    ReDim temp_fPts(0 To 18)
    temp_fPts(0).x = 68.8889: temp_fPts(0).y = 196.667
    temp_fPts(1).x = 133.333: temp_fPts(1).y = 196.667
    temp_fPts(2).x = 220#: temp_fPts(2).y = 194.444
    temp_fPts(3).x = 291.111: temp_fPts(3).y = 194.444
    temp_fPts(4).x = 385.556: temp_fPts(4).y = 194.444
    temp_fPts(5).x = 451.111: temp_fPts(5).y = 194.444
    temp_fPts(6).x = 527.778: temp_fPts(6).y = 193.333
    temp_fPts(7).x = 593.333: temp_fPts(7).y = 193.333
    temp_fPts(8).x = 657.778: temp_fPts(8).y = 193.333
    temp_fPts(9).x = 703.333: temp_fPts(9).y = 193.333
    temp_fPts(10).x = 664.444: temp_fPts(10).y = 155.556
    temp_fPts(11).x = 555.556: temp_fPts(11).y = 181.111
    temp_fPts(12).x = 490#: temp_fPts(12).y = 205.556
    temp_fPts(13).x = 403.333: temp_fPts(13).y = 181.111
    temp_fPts(14).x = 327.778: temp_fPts(14).y = 218.889
    temp_fPts(15).x = 106.667: temp_fPts(15).y = 248.889
    temp_fPts(16).x = 156.667: temp_fPts(16).y = 172.222
    temp_fPts(17).x = 188.889: temp_fPts(17).y = 212.222
    temp_fPts(18).x = 262.222: temp_fPts(18).y = 177.778

    myPoints.SetFeaturePoints -1, temp_fPts

    'create best-fit circle
    Dim BestFitLine As McLines
    myPoints.mlPtBestFitLineAsLine.OutliersFraction = 0
    Set BestFitLine = myPoints.mlPtBestFitLineAsLine.Value.Duplicate
    With BestFitLine
        .AutoDisplay = True
        .DisplayedObjects.SetColors &HFF0000   'make it magenta
        .DisplayedObjects.SetBorderWidth 2 'and fatter
    End With

    Dim BestFitLine2 As McLines
    'set 50% as outliers
    myPoints.mlPtBestFitLineAsLine.OutliersFraction = 0.5
    Set BestFitLine2 = myPoints.mlPtBestFitLineAsLine.Value
    With BestFitLine2
        .AutoDisplay = True
        .DisplayedObjects.SetColors &HFF00&   'make it green
        .DisplayedObjects.SetBorderWidth 2 'and fatter
    End With

    MsgBox "Blue best-fit line is created based on all points" & vbCrLf & _
    "Green best-fit line is created discarding 50% of outliers"
End Sub 'ShowBestFitFeatures

'The ShowBest-fit features example shows how to create best-fit Arc
'and get arc parameters from a best-fit arc and polyline
Public Sub ShowBestFitArc()
    ResetAllStandardFeatures 'remove any existing features
    If uLoadExampleImage("GEAR2.TIF") Then Exit Sub

    Dim myPoints As McPoints
    Set myPoints = ActiveImage.PointFeatures
    myPoints.AutoDisplay = True

    'add points
    ReDim temp_fPts(0 To 5)
    temp_fPts(0).x = 285.859: temp_fPts(0).y = 125.063
    temp_fPts(1).x = 384.81: temp_fPts(1).y = 97.5769
    temp_fPts(2).x = 470.018: temp_fPts(2).y = 122.315
    temp_fPts(3).x = 541.483: temp_fPts(3).y = 221.266
    temp_fPts(4).x = 537.36: temp_fPts(4).y = 322.966
    temp_fPts(5).x = 516.745: temp_fPts(5).y = 362.821

    myPoints.SetFeaturePoints -1, temp_fPts

    'create best-fit arc
    Dim BestFitArc As McLines
    Set BestFitArc = myPoints.mlPtBestFitArcAsLine.Value
    BestFitArc.AutoDisplay = True
    BestFitArc.DisplayedObjects.SetColors &HFF0000   'make it magenta
    BestFitArc.DisplayedObjects.SetBorderWidth 2 'and fatter

    'add center as point
    myPoints.SetFeaturePoints 6, Array(BestFitArc.mLnBestFitArcCenterX.Value(0), BestFitArc.mLnBestFitArcCenterY.Value(0))

    'get arc values
    MsgBox "Best-fit Arc is created with the following parameters:" & vbCrLf & _
    "Center " & McToText(BestFitArc.mLnBestFitArcCenterX.Value) & " : " & McToText(BestFitArc.mLnBestFitArcCenterY.Value) & vbCrLf & _
    "Radius " & McToText(BestFitArc.mLnBestFitArcRadius.Value) & " Angle " & McToText(BestFitArc.mLnBestFitArcAngle.Value)

    'draw new arc
    ReDim temp_fPts(0 To 4)
    temp_fPts(0).x = 230.886: temp_fPts(0).y = 180.036
    temp_fPts(1).x = 213.02: temp_fPts(1).y = 294.105
    temp_fPts(2).x = 266.618: temp_fPts(2).y = 397.179
    temp_fPts(3).x = 382.061: temp_fPts(3).y = 435.66
    temp_fPts(4).x = 470.018: temp_fPts(4).y = 409.548
    Dim myLines As McLines
    Set myLines = ActiveImage.LineFeatures
    myLines.SetFeaturePoints 0, temp_fPts

    'add center as point
    myPoints.SetFeaturePoints 7, Array(myLines.mLnBestFitArcCenterX.Value(0), myLines.mLnBestFitArcCenterY.Value(0))

    'get arc values
    MsgBox "Arc is drawn with the following parameters:" & vbCrLf & _
    "Center " & McToText(myLines.mLnBestFitArcCenterX.Value) & " : " & McToText(myLines.mLnBestFitArcCenterY.Value) & vbCrLf & _
    "Radius " & McToText(myLines.mLnBestFitArcRadius.Value) & " Angle " & McToText(myLines.mLnBestFitArcAngle.Value)
End Sub 'ShowBestFitArc
See Also