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.
I have a ROUTINE that does this individually but I would like to do this as a group.
Thanks.
-- Matt
0
Best Answers
-
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
Yuri0 -
Hi Matt,
Yes, your solution is correct, you can use sf.SfClass for feature classification very efficiently.
Yuri0
Answers
-
2021-03-12-095550Yuri --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 WithIn 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 byIf (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 IfThe 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)
.SelectionFlag = McMeasurements.enumMMSelTypes.mcmmsfAddWithReset
.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
0 -
2021-03-14-151604Yuri --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 IfI will give this a shot ASAP.Thanks again.-- Matt
0 -
2021-03-14-154904Yuri --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
0 -
2021-03-15-103118Yuri --The CODE you provided gave me the guidance needed to make the APP much more efficient.Thanks again.-- Matt
0
Categories
- All Categories
- 961 Image-Pro v9 and higher
- 9 Image-Pro FAQs
- 18 Image-Pro Download & Install
- 448 Image-Pro General Discussions
- 486 Image-Pro Automation (Macros, Apps, Reports)
- 20 AutoQuant Deconvolution
- 2 AutoQuant Download & Install
- 18 AutoQuant General Discussions
- 195 Image-Pro Plus v7 and lower
- 3 Image-Pro Plus Download & Install
- 106 Image-Pro Plus General Discussions
- 86 Image-Pro Plus Automation with Macros
- 19 Legacy Products
- 16 Image-Pro Premier 3D General Discussions
- 26 Image-Pro Insight General Discussions