# Change CLASSIFICATION of FEATURES with CODE . . .

2021-03-11-183551

All --

I have an image that has approximately 100 features in it that have been found with a THRESHOLD and a COUNT.

After the COUNT all of the features are in CLASS 1

I create CLASS 2 and I would like to reclassify some of the features with CODE based on the position of each feature in the image.

I have code that will perform this operation but it does it one by one and it takes about 20 seconds to work through the 100 features in the image.

In reality I determine the DISTANCE of each FEATURE CENTER XY from a REFERENCE CENTER XY (perhaps the UPPER LEFT IMAGE CORNER) in the image.  I would like an efficient way to classify each FEATURE as being CLASS 1 NEAR (< 1 mm DISTANCE) or CLASS 2 FAR (>= 1 mm DISTANCE) from the REFERENCE XY.

I have a ROUTINE that does this individually but I would like to do this as a group.

Thanks.

-- Matt

• edited March 2021 Answer ✓
Hi Matt,

The most efficient way to classify objects by distance to a point is to use the distance map: create distance map (3D Filters: Distance map) from the point of interest (place a black dot on white image) and transfer object outlines to the map (using Features Manager or copy map to the original image using Calc operations) and measure the Intensity Mean, which will correspond to the distance:

then you can classify the object by Intensity Mean. This method will work fast even when you have hundreds of thousands of objects.

If you have only 100 objects, the direct distance calculation can also work fast (milliseconds) if you use code like this:
```        For Each sf As McMMSubFeature In ThisApplication.ActiveImage.MeasurementsData.SubFeatures
Dim x as Double=sf.Value(eMeasures.RgnCentroidX)
Dim y as Double=sf.Value(eMeasures.RgnCentroidY)
Dim dist As Double=System.Math.Sqrt(x*x+y*y)'distance from the top-left corner
sf.SfClass=1+dist/100'classify by distance
Next
ThisApplication.ActiveImage.MeasurementsData.BeginUpdateBlock(False)'refresh
```
Yuri
Hi Matt,

Yes, your solution is correct, you can use sf.SfClass for feature classification very efficiently.

Yuri

• 2021-03-12-095550

Yuri --

Thank you for the CODE.  I think it may help but then I think I have to interact with the CLASSIFICATION TOOL to set the CLASS LIMITS.  That might be the best way but . . .

In my current code, I create two CLASSES as shown below.

With Measure.MeasurementsCommands.Options(Nothing)
.Classes = New System.Collections.Generic.List(Of MMClassDescr)
.Classes.Add(New MMClassDescr("CENTER",System.Drawing.Color.FromArgb(CType(255, Byte),CType(0, Byte),CType(0, Byte)),ePointShape.LargeTarget90))
.Classes.Add(New MMClassDescr("RING",System.Drawing.Color.FromArgb(CType(255, Byte),CType(255, Byte),CType(0, Byte)),ePointShape.LargeTarget45))
.Run(doc1)
End With

In the ROUTINE BELOW, I flip a FEATURE into CENTER CLASS 1 if the DISTANCE is SHORT and I flip the FEATURE into RING CLASS 2 if the DISTANCE is LONG by

If (MyDistance < 1.5) _
Then

'UPDATE THE CLASSIFICATION FOR THIS FEATURE TO 1
UpdateClassification(MyDataTable.SubFeature(MyN).Name, 1)

Else

'UPDATE THE CLASSIFICATION FOR THIS FEATURE TO 2
UpdateClassification(MyDataTable.SubFeature(MyN).Name, 2)

End If

The CODE for UpdateClassification is below.

Is there a way that I can build a list of the FEATURES that need to be in the CENTER CLASS 1 and then set them all with some efficient code and then build a list of the FEATURES that need to be in the RING CLASS 2 and then set them all with some efficient code?

Thanks.

-- Matt

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

Public Function UpdateClassification(MyFeatureName As String, MyClassification As Integer)

Dim image1, doc1
Dim var1 = MyFeatureName, meas1

With Application.DocumentCommands.ActiveImage(Nothing)
.Run(image1)
End With

With Application.DocumentCommands.Define(Nothing)
.Run(image1, doc1)
End With

With Measure.MeasurementsCommands.Define(Nothing)
.Run(var1, meas1)
End With

With Measure.MeasurementsCommands.Selection(Nothing)
.Run(doc1, meas1)
End With

With Measure.MeasurementsCommands.Options(Nothing)
.ActiveClass = MyClassification
.Run(doc1)
End With

With Measure.MeasurementsCommands.ApplyClass(Nothing)
.Run(doc1)
End With

End Function

• 2021-03-14-151604

Yuri --

Looking at your code again I believe that I understand your example better now.

I believe that I can replace your

`                sf.SfClass=1+dist/100'classify by distance`

with something like

`                'CLASSIFY BASED ON DIST LT 1.5 or GTE 1.5                If (dist < 1.5 ) _                   Then                       'CENTER CLASS (LT 1.5)                       sf.SfClass = 1                    Else                       'RING CLASS (GTE 1.5)                       sf.SfClass = 2                   End If`
I will give this a shot ASAP.

Thanks again.

-- Matt

• 2021-03-14-154904

Yuri --

I used the CODE you provided with a modification as shown in my message above and the CLASSIFICATION now happens almost instantly rather than taking about .25 seconds per feature using the original CODE that I wrote.

Thank you very much.

-- Matt

• 2021-03-15-103118

Yuri --

The CODE you provided gave me the guidance needed to make the APP much more efficient.

Thanks again.

-- Matt