Dynamic angle change measurement
Hi,
How can I measure the 'change of angles' of a moving object? I am able to measure the change of diameter or surface area of deformable moving object but for the contact angle, I cannot do it. I will highly appreciate any help. If you need any more info please let me know.
Thanks
Abrar
How can I measure the 'change of angles' of a moving object? I am able to measure the change of diameter or surface area of deformable moving object but for the contact angle, I cannot do it. I will highly appreciate any help. If you need any more info please let me know.
Thanks
Abrar
0
Best Answer
-
Hi Abrar,
Since the Relative measurements are based on selected objects you must have objects selected before running the macro. Or activate macro recording before object selection and record all steps. You can also add an interactive step asking user to select objects and continue. (Check the forum how to make a command to be interactive)
Yuri0
Answers
Abrar --
Would it be possible for you to post a series of images that illustrate the challenge that you face?
If you can do that I'm sure that someone on the forum can help you achieve your goal.
-- Matt
There is "Direction" measurement available that reports orientation (angle) of the object. Check if it will work for you.
Yuri
here are some images of contact angle measurement that I measured manually. But I want to measure them for each frame of the video using count options. Thanks in advance.
Abrar --
Thank you for your example images. They assist in understanding your challenge.
I must leave my desk for an appointment but I will look at this early tomorrow (THU) AM (HOUSTON TEXAS TIME) and reply.
Thanks again.
-- Matt
Every point of the contour has different angle, so you have to detect specific points on the edge and determine the angle.
One of the ways would be to use Sculpture filter, which is also called "Phase filter" based on the Sobel detection, which assigns intensity to the pixels corresponded to the orientation of the edge gradient, so you can measure intensity of the result pixel and report orientation of the edge. The screenshot below illustrates this. I binarized image first and applied Sculpture filter, the right image is pseudo-colored to show that every pixel on the sphere boundary has different intensity.
Another way is to detect specific points on the outline, for example by using 2 horizontal lines with fixed distance between them and then calculate angle based on the start/end points of these lines.
On the screenshot below, these are L1 and L2 lines, these lines are created using the "Snap" tool, so they start/end exactly on the edge of the object. Then the derived CCD5 line between line start points is created and the angle AB6 is created between lines CCD5 and L1:
These measurements can be automated by a macro.
Yuri
Yuri --
The information you provided looks great.
The second section is pretty close to the way I was going to suggest going.
I hope this is helpful to Abrar.
-- Matt
Thanks
Abrar
I was talking about Relative group on the Measure tab:
You can create some measurements manually (e.g. L1 and L2), select them and create derived (relative) measurements based on the selected features, it can be Starting Point, Center-to-center distance, Angle between lines, etc. Using these tools you can create the Angle measurement you want based on the L1 and L2 lines in several steps.
Yuri
I did what you said but while running macro I got the message like, "No objects are selected. Please select 2 or more objects and try again." Where am i doing mistakes ?
Thanks
Abrar
I am able to run the macros and thanks to you but I am still facing problems measuring angles. Because angles lines are not moving with the selected objects. For your understanding I have attached two samples. (I used 'snap to straight edge tool ' to draw lines.)
During Macro recording:
Implementation of macro in new figure:
Thanks in advance.
The steps that create Angle measurements I described assume that the lines L1 and L2 are created at the right locations. The steps of creating L1 and L2 is a different task, which you should define.
As I see your images have different location of the drop, so you have to figure out how to put the lines with given vertical offset to the right places. You may either try to align all images, so the base line is always the same and then write a macro that draws L1 and L2 at the right Y positions (you can use Snap feature drawing lines, Auto Adjust Template, to snap the line to drop edges) or just draw L1 and L2 manually on every image.
Yuri
Based on Abrar's uploaded image, we need to select 4 points to draw the lines L1 and L2. What we can do is, we can fix two values of 'Y' for writing the macro and select 4 values of 'X' based on the maximum intensity for that frame. Later, we can draw a derived line from the starting points of L1 and L2, followed by drawing a derived angle. We can run a loop for all the frames using this same code. But I am unable to find the syntax to define the X coordinate of the point as a variable. Can you please help?
Thanks in advance!
Viraj
The approach I described with Relative measurements and Snap features assumed that the Y positions of L1 and L2 lines are always the same, only the end-points (X coordinates) are adjusted on every image.
You may try to align all your images (Align tool) and put them into a sequence where all the images will have the same Y position of the base line (corresponded to Y coordinate of L1), then you just load the same template that includes L1, L2 lines and all derived angles on every frame and execute Auto-Adjust Template.
Another way, more complicated, which you asked, is to create a macro that will generate all the lines from user-defined XY positions. In that case you will need to record a macro that creates all the lines and derived features (from the beginning, starting from L1) and then replace recorded coordinates of lines by variables. From something like this:
to this:
'define external variable Dim pStart1 As System.Drawing.PointF Dim pEnd1 As System.Drawing.PointF '... With Measure.MeasurementsCommands.Add(CreateMeasurements) .MeasurementType = McMeasurements.enumMMSTypes.mmtsLine .Points = New System.Collections.Generic.List(Of System.Drawing.PointF) .Points.Add(New System.Drawing.PointF(pStart1.x,pStart1.y)) .Points.Add(New System.Drawing.PointF(pEnd1.x,pEnd1.Y)) .FeatureName = "L1" .SnapFeature = True .SnapOptions.SnapToImage = McMMOptions.mcmmSnapMethods.mcmmSnapWholeLine .SnapOptions.SnapRadius = 16 .SnapOptions.CaliperMatchLength = 7 .SnapOptions.CaliperWidth = 3 .Run(doc1, meas1) End With With Measure.MeasurementsCommands.AutoAdjust(CreateMeasurements) .Run(doc1) End With
and control coordinate variables (pStart1, pEnd1,...) by your macro.
Yuri
In reference to the first solution which you mention, my images are already aligned. Therefore, the Y coordinates of the point is fixed. Can you please explain me how to define a variable X coordinate using Relative measurements and Snap features and how to execute Auto-Adjust Template.
Thank you very much
I will explain how to use templates doing you measurements.
1. Create template measurements that include L1, L2 and all derived features and angles.
a) Switch on Template mode option in the Snap drop-down:
b) Activate the Snap mode (Adjust line length) and draw L1 and L2 lines on the correct Y position, but make them wider then the widest object on any frame. Note, that they will not "Snap" to edges when you release the mouse, because the Template mode is active.
c) Add all derived measurements based on L1, L2 (they will also look incorrect, but that's not important for now).
2. Save the template to IQM file using the Save button in the measurements Data Table. This template will be used on all frames.
3. Select the frame you need, cleanup all the measurements and load the IQM file (saved on step 2).
4. Click the Auto-Adjust Template menu item, the lines will be "snapped" to the object edges and all the measurements adjusted accordingly:
6. Collect measurement values, including AB6 angle to to Data Collector.
5. Repeat steps 3 to 6 for all frames, it will give you the angle measurements for all the phases. These steps can be automated by a macro, every step is macro recordable (just activate macro recording and do the steps).
Yuri
Viraj --
Please see the following for a suggested method to handle your challenge.
The measurements generated by this procedure could be used to get the data that you have shown is of interest.
This type of procedure could be used on ROIS across an image or on IMAGES in a SEQUENCE.
The spacing of the MASK LINES could be reduced to make this more accurate and the procedure could also be automated.
I hope this information is helpful.
-- Matt
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
ORIGINAL IMAGE (created from a MOVIE of an OIL DROP)
ORIGINAL IMAGE + MASK with HORIZONTAL LINES + MASK with VERTICAL LINES
H MASK MINUS ORIGINAL IMAGE and V MASK MINUS ORIGINAL IMAGE
ROI on HMASK over OIL DROP + BRIGHT THRESHOLD + COUNT
ROI on VMASK over OIL DROP + BRIGHT THRESHOLD + COUNT
I used your method and I think I am getting the results as required. All thanks to you!
I tried to automate the process using a Macro which I think works fine. The thing is I have to Click on the Run icon for every frame:
Is there anyway to write a macro instead of clicking on the 'Run' icon for every frame as I have more than 54000 frames, all in all.
Thank you again!
Regards
Viraj
You can use a macro that loops through all frames of the image and calls the macro on every frame, (the macro should place measurements on the image, execute AutoAdjust and export measurements to Data Collector).
Here is the example of such macro:
Public Sub MeasureAllFrames If ThisApplication.ActiveImage Is Nothing Then Exit Sub 'go through all frames of the image For i As Integer=0 To ThisApplication.ActiveImage.FrameCount-1 'activate frame ThisApplication.ActiveImage.ActiveFrameIndex=i 'call your macro that measures active image 'Call MyMacro Next End Sub
Yuri
It's hard to tell without seeing what you have there. Be sure that you don't miss anything.
Also, this is just a sample macro, you should create your own macro that would call your functions.
Yuri
Imports MediaCy.Viewers.Image Imports MediaCy.Addins.Measurements Public Module Module3000 Public Function NewMacro3000() As SimpleScript NewMacro3000 = New SimpleScript Dim window1, doc1 With Application.WindowCommands.Active(NewMacro3000) .Run(window1) End With With View.ImageViewCommands.Options(NewMacro3000) .ActiveFrameIndex = 1 .Run(window1) End With With Application.RibbonCommands.SelectRibbonTab(NewMacro3000) .TabName = "Measure" .Run() End With With Application.DocumentCommands.Active(NewMacro3000) .Run(doc1) End With With Measure.MeasurementsCommands.DeleteAll(NewMacro3000) .Run(doc1) End With With Measure.MeasurementsCommands.Open(NewMacro3000) .FileName = "D:\xyz.iqm" .FilterIndex = 1 .Run(doc1) End With With Measure.MeasurementsCommands.AutoAdjust(NewMacro3000) .Run(doc1) End With With Measure.Measurements.TableCommands.SendToExcel(NewMacro3000) .UseStatistics = False .Run(doc1) End With End Function End Module The above is my Macro. Now is it possible to find a solution?
This is my original macro. I need to run this for all the frames instead of one using the script which you told.
Thanks
Viraj
Just paste my macro below your's and call NewMacro3000 in the loop.
Yuri
I pasted the following script in between the last two lines, 'End Function' and 'End Module' of my Macro:
Public Sub MeasureAllFrames If ThisApplication.ActiveImage Is Nothing Then Exit Sub 'go through all frames of the image For i As Integer=0 To ThisApplication.ActiveImage.FrameCount-1 'activate frame ThisApplication.ActiveImage.ActiveFrameIndex=i 'call your macro that measures active image Call NewMacro3000 Next End Sub Still the Macro runs for Frame number 2 only. Thanks Viraj
Yuri
Still it is capturing for only one frame. I am really stuck!
Thanks
Viraj
Thank you very much. It is working I think. I will let you know about the progress if the results are correct. Thanks again.
Best Regards
Viraj