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

Retrieve mean object size for classes

HI all, 

I found this code to retrieve the number of objects within two classes - I need the number and the mean obj size and locate to global vars (for module). 

However, the code works fine, but I cannot define a condition in which I can retrieve for each class separately:

This script basically works
Public Sub PrintClassStats()

        Dim im As McImage=ThisApplication.ActiveImage
        If im Is Nothing Then Exit Sub 'no image
        Dim md As McMMData=im.MeasurementsData
        If md.Count=0 Then Exit Sub'no data
        Dim classes As MMClasses=McMeasurements.ThisAddin.Options.Classes
        Dim nClasses As Integer=classes.Items.Count


        
        For Each cl As MMClassDescr In classes.Items.Values
            'get count of objects of this class
            Dim nObj As Integer=0
            For Each sf As McMMSubFeature In md.SubFeatures
                If sf.Value(eMeasures.AnyClass)=cl.Value Then nObj+=1
            Next

           Debug.Print "Class name = " & cl.DisplayName & ", Number of Objects = " & nObj.ToString

        Next
    End Sub

Here my try, whereas second condition (else) is never met:

 Public Sub PrintClassStats()

        Dim im As McImage=ThisApplication.ActiveImage
        If im Is Nothing Then Exit Sub 'no image
        Dim md As McMMData=im.MeasurementsData
        If md.Count=0 Then Exit Sub'no data
        Dim classes As MMClasses=McMeasurements.ThisAddin.Options.Classes
        Dim nClasses As Integer=classes.Items.Count
'those should be globals
Dim area1, area2, countCl1, countCl2
For Each cl As MMClassDescr In classes.Items.Values 'get count of objects of this class Dim nObj As Integer=0 For Each sf As McMMSubFeature In md.SubFeatures If sf.Value(eMeasures.AnyClass)=cl.Value Then nObj+=1 Next If cl.Value = 1 Then ' also tried 0, cl.description = "Class 1" etc. countCl1 = nObj Else ' no matter what I DO HERE - CONDITION IS NEVER MET countCl2 = nObj End If Debug.Print "Class name = " & cl.DisplayName & ", Number of Objects = " & nObj.ToString Debug.Print "count1 = " & countCl1.ToString Debug.Print "count2 = " & countCl2.ToString Next End Sub

Last but not least no idea how to retrieve the info for mean object size.
I tried this one:

area1 = sf.Value(eMeasures.RgnArea)


I'm sure you can check very quickly, while I can't find a way how to do right. 

Thx
Daniel

Best Answer

  • Answer ✓
    Hi Daniel,

    Your macro had some issues with array definitions and the loop entry. Here is the modified version that works:

    Public Sub PrintClassStats()
    
            Dim im As McImage=ThisApplication.ActiveImage
            If im Is Nothing Then Exit Sub 'no image
            Dim md As McMMData=im.MeasurementsData
            If md.Count=0 Then Exit Sub'no data
            Dim classes As MMClasses=McMeasurements.ThisAddin.Options.Classes
            Dim nClasses As Integer=classes.Items.Count
            Dim count As Integer()
            Dim area As Double()
    
            ReDim count(nClasses)
            ReDim area(nClasses)
            Debug.Clear
    
            'Debug.Print "Number of classes = " & nClasses.ToString
            For Each cl As MMClassDescr In classes.Items.Values
                'get count of objects of this class
                For Each sf As McMMSubFeature In md.SubFeatures
                    If sf.Value(eMeasures.AnyClass)=cl.Value Then
                        'sum Objects
                        count(cl.value-1) += 1
                        'sum Area
                        area(cl.value-1) += sf.Value(eMeasures.RgnArea)
                    End If
                Next
                'get Average Area
                If count(cl.value-1)>0 Then
                    area(cl.value-1)=area(cl.value-1)/count(cl.value-1)
                End If
                'check Stats
                Debug.Print "Class name = " & cl.DisplayName & ", Number of Objects = " & count(cl.value-1).ToString & ", Area(mean) = " & area(cl.value-1).ToString
    
            Next
        End Sub
    

    Yuri

Answers

  • Hi Daniel,

    Class states can be directly reported in the measurement table by grouping "By Class" or in the Data Collector in the "Measurements Class Stats" table.

    If you want to retrieve it in the code, here is the modified macro:

        Public Sub PrintClassStats()
            Dim im As McImage=ThisApplication.ActiveImage
            If im Is Nothing Then Exit Sub 'no image
            Dim md As McMMData=im.MeasurementsData
            If md.Count=0 Then Exit Sub'no data
            Dim classes As MMClasses=McMeasurements.ThisAddin.Options.Classes
            Dim nClasses As Integer=classes.Items.Count
    
            For Each cl As MMClassDescr In classes.Items.Values
                'get count of objects of this class
                Dim nObj As Integer=0
                Dim area As Double=0
                For Each sf As McMMSubFeature In md.SubFeatures
                    If sf.Value(eMeasures.AnyClass)=cl.Value Then
                        nObj+=1
                        area+=sf.Value(eMeasures.RgnArea)
                    End If
                Next
                Debug.Print(String.Format("Class name = {0}, Number of Objects = {1}, Average Area = {2}", cl.DisplayName,nObj,IIf(nObj=0,0,area/nObj)))
            Next
        End Sub
    

    Regards,

    Yuri
  • Hi all, 

    I already resolved the issue, at least for the count:

    This code works for number of objects, but not yet for mean size. 

    Public Sub PrintClassStats()
    
            Dim im As McImage=ThisApplication.ActiveImage
            If im Is Nothing Then Exit Sub 'no image
            Dim md As McMMData=im.MeasurementsData
            If md.Count=0 Then Exit Sub'no data
            Dim classes As MMClasses=McMeasurements.ThisAddin.Options.Classes
            Dim nClasses As Integer=classes.Items.Count
    Dim area1, area2,count, area
    
    ReDim count(nClasses) As Double
    ReDim area(nClasses) As Double
    Debug.Clear
    
            'Debug.Print "Number of classes = " & nClasses.ToString
            For Each cl As MMClassDescr In classes.Items.Values
                'get count of objects of this class
                Dim nObj As Integer=0
                For Each sf As McMMSubFeature In md.SubFeatures
                    If sf.Value(eMeasures.AnyClass)=cl.Value Then nObj+=1
                    Debug.Print sf.Value(eMeasures.RgnArea)
                Next
    
                count(cl.value-1) = nObj
    
                area(cl.value-1) = sf.Value(eMeasures.RgnArea)
    
               Debug.Print "Class name = " & cl.DisplayName & ", Number of Objects = " & nObj.ToString
    
    Debug.Print count(0)
    Debug.Print count(1)
    
    Debug.Print area(0)
    Debug.Print area(1)
    
    
    
            Next
        End Sub


  • Hi all, 

    Sorry to have bothered, but think I have resolved it now totally :-0. Here the code that seems to work:

    Public Sub PrintClassStats()
    
            Dim im As McImage=ThisApplication.ActiveImage
            If im Is Nothing Then Exit Sub 'no image
            Dim md As McMMData=im.MeasurementsData
            If md.Count=0 Then Exit Sub'no data
            Dim classes As MMClasses=McMeasurements.ThisAddin.Options.Classes
            Dim nClasses As Integer=classes.Items.Count
    
    Dim count, area
    Dim AreaSum As Double = 0
    'later set to globals Dim areaCl1, areaCl2, OD1, OD2, CountCl1, CountCl2 ReDim count(nClasses) As Double ReDim area(nClasses) As Double Debug.Clear 'Debug.Print "Number of classes = " & nClasses.ToString For Each cl As MMClassDescr In classes.Items.Values 'get count of objects of this class Dim nObj As Integer=0 For Each sf As McMMSubFeature In md.SubFeatures If sf.Value(eMeasures.AnyClass)=cl.Value Then nObj+=1 If sf.Value(eMeasures.AnyClass)=cl.Value Then AreaSum = AreaSum + sf.value(eMeasures.RgnArea) Next count(cl.value-1) = nObj area(cl.value-1) = AreaSum Debug.Print "Class name = " & cl.DisplayName & ", Number of Objects = " & nObj.ToString Debug.Print count(0) Debug.Print count(1) Debug.Print area(0) Debug.Print area(1) Next CountCl1 = count(0) CountCl2 = count(1) areaCl1 = area(0) areaCl1 = area(1) - area(0) OD1 = CountCl1/areaCl1 OD2 = CountCl2/areaCl2 End Sub



Sign In or Register to comment.