Home Image-Pro Automation (Macros, Apps, Reports)

CODE to SELECT the OBJECTS in a LEARNING CLASSIFIER CLASS . . .

All --

The IMAGES below illustrate my problem but here is the description.

I have an image that has multiple types of objects within it.  In this example they are CIRCLES, SQUARES, PARALLELOGRAMS, and TRIANGLES.  I can find the objects and classify them using the LEARNING CLASSIFIER.  This is illustrated in the FIRST IMAGE below.

I would then like to be able to SELECT all of the objects in one of the classes and then work with just that set of objects.  That is illustrated in the SECOND IMAGE below where I have manually worked with the DATA TABLE to select the SQUARES.

Via the RECORD MACRO I got

    Public Function NewMacro() As SimpleScript
        NewMacro = New SimpleScript
        Dim doc1

        With Application.DocumentCommands.Active(NewMacro)
            .Run(doc1)
        End With

        With Measure.MeasurementsCommands.ShowClass(NewMacro)
            .Action = McMeasurements.enumShowMeasFlags.smfShowAll
            .FeatureClass = 2
            .Run(doc1)
        End With

        With Measure.MeasurementsCommands.SelectAll(NewMacro)
            .Run(doc1)
        End With

        With Measure.MeasurementsCommands.ShowAll(NewMacro)
            .Action = McMeasurements.enumShowMeasFlags.smfShowAll
            .FeatureClass = -1
            .Run(doc1)
        End With

    End Function

when I used the SHOW FEATURE within the MEASUREMENT TABLE and the SELECT ALL within the SELECT MEASUREMENTS TOOL and the SHOW ALL within the HIDE / SHOW OVERLAYS TOOL.

Is there a more efficient way to do something like

    SELECT ALL OBJECTS OF CLASS SQUARE

in CODE? 

Thanks in advance.

-- Matt










Best Answers

  • edited March 2019 Answer ✓
    Hi Matt,

    Your code is already efficient, but if you want to use lower level code, here is a sample macro that shows that:

        Public Sub SelectClass2()
            'select all measurement features of class 2
            SelectClass(2)
        End Sub
    
        Public Sub SelectClass(ind As Integer)
            If ThisApplication.ActiveImage Is Nothing Then Exit Sub
            For Each sf As McMMSubFeature In ThisApplication.ActiveImage.MeasurementsData.SubFeatures
                sf.Selected=(sf.SfClass=ind)'select the feature of the given class
            Next
        End Sub
    

    Yuri
  • Answer ✓
    Matt,

    Check how it works for your application and let me know if it's not fast enough. These operations involve updates of graphics on the image, which takes time. If you just want to have statistics from certain groups of objects, then there are other ways to get it faster, without changing display.
    Like this:

        Public Sub CalcStatsClass2()
            'calculate statistics of class 2
            CalcClassStats(2)
        End Sub
    
        Public Sub CalcClassStats(ind As Integer)
            If ThisApplication.ActiveImage Is Nothing Then Exit Sub
            Dim vals As New System.Collections.ArrayList
            For Each sf As McMMSubFeature In ThisApplication.ActiveImage.MeasurementsData.SubFeatures
                If sf.SfClass=ind Then
                    vals.Add(sf.Value(eMeasures.RgnArea))
                End If
            Next
            Dim bst As Mediacy.IQL.ObjectManager.BASIC_STATISTICS
            bst = ThisApplication.GlobalTools.McBasicStatistics(vals.ToArray()) 'get the stats
            MsgBox(String.Format("Mean area of class {0} = {1}, StDev = {2}, Count = {3}",ind,bst.Mean,bst.StdDev, bst.Count))
        End Sub
    


    Yuri

Answers

  • 2019-03-26-091013

    Yuri --

    Thank you for your guidance on this.

    I'll create a sample image and time both routines to see which one executes faster.  This application is handling LOTS of objects so efficient CODE is one thing but efficient operation is most important.

    Thanks again.

    -- Matt


  • 2019-03-26-153602

    Yuri --

    Thank you for the additional information.  I think I can make use of CalcClassStats to speed something up in my CODE.  Every second counts!

    Here is the results of my testing . . .

    On an image with 2277 objects, SelectClass2MMB took about 77% of the time SelectClass2Yuri took to select 1175 OBJECTS (in CLASS 2) out of the 2277 OBJECTS in the image.



    The two routines tested against each other are below.

    In this situation the RECORDED MACRO is longer but more efficient that the LOW LEVEL CODE.

    Since some of the images this application works with have 10,000 or 20,000 objects, being efficient pays big dividends.

    Thank you very much for the assistance on this.

    -- Matt


        Public Function SelectClass2MMB()
    
            Debug.Print "SelectClass2MMB -- START" & vbTab & Now() & vbTab & system.Environment.TickCount
    
            'CONNECT WITH THE ACTIVE DOCUMENT
            Dim doc1
            With Application.DocumentCommands.Active(Nothing)
                .Run(doc1)
            End With
    
            'Deactivate all tools by selecting the NO TOOL to set up consistently
            With Measure.Measurements.ToolsCommands.Select(Nothing)
                .Tool = eMMTool.NoTool
                .Run(doc1)
            End With
    
            'TURN ON THE SELECTION TOOL TO SET UP CONSISTENTLY
            With Measure.MeasurementsCommands.Selection(NewMacro)
                .Run(doc1)
            End With
    
            'PERFORM A SHOW ALL TO TO SET UP CONSISTENTLY
            With Measure.MeasurementsCommands.ShowAll(Nothing)
                .Action = McMeasurements.enumShowMeasFlags.smfShowAll
                .FeatureClass = -1
                .Run(doc1)
            End With
    
            With Measure.MeasurementsCommands.ShowClass(Nothing)
                .Action = McMeasurements.enumShowMeasFlags.smfShowAll
                .FeatureClass = 2
                .Run(doc1)
            End With
    
            With Measure.MeasurementsCommands.SelectAll(Nothing)
                .Run(doc1)
            End With
    
            With Measure.MeasurementsCommands.ShowAll(Nothing)
                .Action = McMeasurements.enumShowMeasFlags.smfShowAll
                .FeatureClass = -1
                .Run(doc1)
            End With
    
            Debug.Print "SelectClass2MMB -- END" & vbTab & Now() & vbTab & system.Environment.TickCount
    
        End Function
    
    
        Public Sub SelectClass2Yuri()
    
            Debug.Print "SelectClass2Yuri -- START" & vbTab & Now() & vbTab & system.Environment.TickCount
    
            'CONNECT WITH THE ACTIVE DOCUMENT
            Dim doc1
            With Application.DocumentCommands.Active(Nothing)
                .Run(doc1)
            End With
    
            'Deactivate all tools by selecting the NO TOOL to set up consistently
            With Measure.Measurements.ToolsCommands.Select(Nothing)
                .Tool = eMMTool.NoTool
                .Run(doc1)
            End With
    
            'TURN ON THE SELECTION TOOL TO SET UP CONSISTENTLY
            With Measure.MeasurementsCommands.Selection(NewMacro)
                .Run(doc1)
            End With
    
            'PERFORM A SHOW ALL TO TO SET UP CONSISTENTLY
            With Measure.MeasurementsCommands.ShowAll(Nothing)
                .Action = McMeasurements.enumShowMeasFlags.smfShowAll
                .FeatureClass = -1
                .Run(doc1)
            End With
    
            'select all measurement features of class 2
            SelectClass(2)
    
            'PERFORM A SHOW ALL TO MAKE THE DELETE SELECTED UPDATE TO SHOW THE NUMBER OF OBJECTS SELECTED
            With Measure.MeasurementsCommands.ShowAll(Nothing)
                .Action = McMeasurements.enumShowMeasFlags.smfShowAll
                .FeatureClass = -1
                .Run(doc1)
            End With
    
            Debug.Print "SelectClass2Yuri -- END" & vbTab & Now() & vbTab & system.Environment.TickCount
    
        End Sub
    
        Public Sub SelectClass(ind As Integer)
            If ThisApplication.ActiveImage Is Nothing Then Exit Sub
            For Each sf As McMMSubFeature In ThisApplication.ActiveImage.MeasurementsData.SubFeatures
                sf.Selected=(sf.SfClass=ind)'select the feature of the given class
            Next
        End Sub
    
    
    


Sign In or Register to comment.