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

More Measurement Outlines

Hello Yuri
You suggested making doughnut areas from a Distance map, which works well. However the code I'm using to increment the threshold level is below. How do you automatically increment the values {1R,261R} using the high level commands produced by recording the steps would mean I would have to manually input them for each cell within the image. Are there any lower level commands that would accept a variable input to change the thresholds.
 With Measure.ThresholdToolCommands.Thresholds(Eroder)
                .AllowOverlap = False
                .Interpretation = eInterpretation.Mono
                .Classes = New System.Collections.Generic.List(Of SegmentationClass)
                .Classes.Add(New SegmentationClass("Class 1",System.Drawing.Color.Blue,New Double(){1R,261R}))
                .Run(ThisApplication.ActiveImage)
            End With

Best Answer

  • edited December 2013 Answer ✓

    Here is another sample macro, which will print thresholds of the active image for all classes, all channels:

        Public Function GetActiveThresholds() As SimpleScript
            GetActiveThresholds = New SimpleScript
            'create command to read thresholds
            With Measure.ThresholdToolCommands.Thresholds(GetActiveThresholds)
                'initialize it from the active document
                .GetFromDocument(ThisApplication.ActiveDocument)
                'read the command parameters, go through all classes
                For Each thrClass As SegmentationClass In .Classes
                    'go through all channels
                    For Each ch As SegmentationChannel In thrClass.Channels
                        Debug.Print (thrClass.DisplayName & " = " & ch.ThresholdMin & ", " & ch.ThresholdMax)
                    Next
                Next
                'don't call Run!
            End With
        End Function

Answers

  • Here is a sample macro:

        Public Function MultiThreshold() As SimpleScript
            MultiThreshold = New SimpleScript
            Dim doc1
            'define start and step, nRanges
            Dim startThreshold As Double=1
            Dim stepThreshold As Double=10
            Dim nRanges As Integer=5
    
            With Application.DocumentCommands.Active(MultiThreshold)
                .Run(doc1)
            End With
    
            With Measure.MeasurementsCommands.Options(MultiThreshold)
                .Segmentation.AutoFindPhase = MediaCy.IQL.Features.mcFindPhase.mcfpManual
                .Segmentation.SegmentationType = McMMOptions.mcmmSegmentationType.mcmmstThresholdSegmentation
                .Run(doc1)
            End With
    
            With Measure.ThresholdToolCommands.Thresholds(MultiThreshold)
                .AllowOverlap = False
                .Interpretation = eInterpretation.Mono
                .Classes = New System.Collections.Generic.List(Of SegmentationClass)
                'add thresholds programmatically
                For i As Integer=0 To nRanges-1
                    .Classes.Add(New SegmentationClass("Class " & (i+1).ToString(),System.Drawing.Color.FromArgb(i*50,255-i*50,i*20), _
                        New Double(){startThreshold+i*stepThreshold,startThreshold+(i+1)*stepThreshold}))
                Next
                .Run(doc1)
            End With
    
        End Function
    

    Yuri

  • Hello Yuri

    That works thanks I didn't realise that you can substitute the values in these higher level commands easily. However I have another question about them, if you can assign variables to them can you also extract data from them as I want a user to threshold an image and then be able to extract the upper and lower threshold values into a variable for use elsewhere, I need to extract them as the user wants it associated with the measurement data.

    Regards

    David

  • edited December 2013
    Hello David,

    Most commands are defined to set data. Reading data is another issue. 
    You you want to get segmentation thresholds interactively defined by user,  you have to read them using ThresholdTool functions. Here is the test macro where user is prompted to set thresholds, which then are saved to outThresholds list.

        Public Function InteractiveThresholds() As SimpleScript
            InteractiveThresholds = New SimpleScript
            Dim doc1
            'define output array for thresholds
            Dim outThresholds As New System.Collections.ArrayList
    
            With Application.DocumentCommands.Active(InteractiveThresholds)
                .Run(doc1)
            End With
    
            With Measure.MeasurementsCommands.Options(InteractiveThresholds)
                .Segmentation.AutoFindPhase = MediaCy.IQL.Features.mcFindPhase.mcfpManual
                .Segmentation.SegmentationType = McMMOptions.mcmmSegmentationType.mcmmstThresholdSegmentation
                .Run(doc1)
            End With
    
            With Measure.ThresholdTool.Gadgets.Histogram(InteractiveThresholds)
                .CheckState = MediaCy.IQL.Application.McCommand.mcCheckState.Checked
                .Run()
            End With
    
            With Measure.ThresholdToolCommands.Thresholds(InteractiveThresholds)
                .AllowOverlap = False
                .Interpretation = eInterpretation.Mono
                .Classes = New System.Collections.Generic.List(Of SegmentationClass)
                .Classes.Add(New SegmentationClass("Class 1",System.Drawing.Color.Blue,New Double(){1,20}))
                'make command interactive
                .Prompt="Please add as many classes as you need and adjust thresholds."
                .Interactive=True
                .InteractionPanel="ThresholdTool"
                .InteractionLocation=McCommand.InteractionPosition.OutsideLeft
                .Run(doc1)
            End With
    
            With Automate.ScriptingCommands.CodeCommand(InteractiveThresholds)
                If .Run() Then
                    ' User Code Here
                    'read thresholds
                    Dim segmData As SegmentationData= McThresholdTool.ThisAddin.GetSegmentationData(ThisApplication.ActiveImage)
                    'read thresholds
                    For Each thrClass As SegmentationClass In segmData.Classes
                        Dim rng As MediaCy.IQL.ObjectManager.DOUBLERANGE
                        rng=thrClass.Thresholds(0)'take only fist channel assuming that our image is monochrome
                        Debug.Print (thrClass.DisplayName & " = " & rng.start & ", " & rng.end)
                        outThresholds.Add(rng)'add to the list
                    Next
                End If
            End With
        End Function
    

    Yuri
  • There is another approach that involves using command properties. It could be easier to use when you know what commands are involved.

    Some commands are initialized from the active image, ThresholdTool.Thresholds is one of them.

    So you can just create a command and read its properties, which will return parameters of the active image.

     

    Sample macro:

        Public Function InteractiveThresholds() As SimpleScript
            InteractiveThresholds = New SimpleScript
            Dim doc1
            'define output array for thresholds
            Dim outThresholds As New System.Collections.ArrayList
    
            With Application.DocumentCommands.Active(InteractiveThresholds)
                .Run(doc1)
            End With
    
            With Measure.MeasurementsCommands.Options(InteractiveThresholds)
                .Segmentation.AutoFindPhase = MediaCy.IQL.Features.mcFindPhase.mcfpManual
                .Segmentation.SegmentationType = McMMOptions.mcmmSegmentationType.mcmmstThresholdSegmentation
                .Run(doc1)
            End With
    
            With Measure.ThresholdTool.Gadgets.Histogram(InteractiveThresholds)
                .CheckState = MediaCy.IQL.Application.McCommand.mcCheckState.Checked
                .Run()
            End With
    
            With Measure.ThresholdToolCommands.Thresholds(InteractiveThresholds)
                .AllowOverlap = False
                .Interpretation = eInterpretation.Mono
                .Classes = New System.Collections.Generic.List(Of SegmentationClass)
                .Classes.Add(New SegmentationClass("Class 1",System.Drawing.Color.Blue,New Double(){1,20}))
                'make command interactive
                .Prompt="Please add as many classes as you need and adjust thresholds."
                .Interactive=True
                .InteractionPanel="ThresholdTool"
                .InteractionLocation=McCommand.InteractionPosition.OutsideLeft
                .Run(doc1)
            End With
    
            'create another command to read thresholds
            With Measure.ThresholdToolCommands.Thresholds(InteractiveThresholds)
                'the ThresholdToolCommands.Thresholds command is initialized from the active image,
                'read the command parameters
                For Each thrClass As SegmentationClass In .Classes
                    Dim rng As MediaCy.IQL.ObjectManager.DOUBLERANGE
                    rng=thrClass.Thresholds(0)'take only fist channel assuming that our image is monochrome
                    Debug.Print (thrClass.DisplayName & " = " & rng.start & ", " & rng.end)
                    outThresholds.Add(rng)'add to the list
                Next
                'don't call Run!
            End With
        End Function
    


    Yuri

Sign In or Register to comment.