# Convert variations in 2 D boundary to 1 D

My goal here is to get the variations in the boundary (see the image) and plot in 1D with respect to a constant axis (either x-axis or y-axis).

Note: The yellow colored boundary is what I am concerned with.

Good day!

[â€¦] variations in the boundary [â€¦]

with respect to what, a circle?

Clueless,

Herbie

PS:
Here is a polar plot that shows the deviation of the contour from a circle around the â€ścenter of massâ€ť of the contour:

`mean = 35.63 Â±6.94 pixel`

You may also have a look at this thread:

Other ways of doing what you want are:

• elliptic Fourier descriptors
• curvature /scale space analysis
• fractal dimension (although the contour you showed does not look fractal)

@anon96376101

Yes, I need the variations with respect to the bounding circle. The image which you have put up is exactly what I am looking for. How did you come up with the Polar Plot?

Regards,
kbimagej

@gabriel

Does ImageJ have any plugins which includes your method? Also, what do you mean by Fractal dimension?

Regards,
kbimagej

Good day!

Here you can get the ImageJ-plugin for the polar transformation:
https://imagej.nih.gov/ij/plugins/polar-transformer.html

For me two ways of defining the crucial center for the transformation appear easily feasible:

1. Center of mass (see â€śSet Measurementsâ€¦â€ť)
2. Center of the fitting circle (see â€śEdit >> Selection >> Fit Circleâ€ť)

Please note that both approaches lead to slightly different results. You must decideâ€¦

Regards

Herbie

1 Like

An implementation for the elliptic fourier analysis:
http://imagejdocu.tudor.lu/doku.php?id=plugin:analysis:fourier_shape_analysis:start

I do not remember an existing plugin for the curvature analysis, but there are plenty of references on how to do it.

1 Like

Hi Herbie,

I got the centers for the ROI in the image posted. I understand the intuition that it has to do something with the variations in radius from the fitting circleâ€™s radius and we have to iterate through varying angles i.e. theta to get the graph. How do I reciprocate this idea so that I get a similar graph as the one you posted using Polar Transformer plugin?

Regards,
kbimagej

Good day,

do you have the the imageJ plugin â€śPolar_Transformer.classâ€ť installed?

1. Then you have to have an image with the binary contour of your image open in ImageJ:

2. Start the plugin and uncheck all of the three check boxes in the appearing dialog. Then click OK.

3. A new dialog appears and for the time being leave it with the given entry of 360. Then click OK.

4. A new dialog appears in which you are to enter the center coordinates. Then click OK.

Youâ€™re done.

Regards

Herbie

Hi Herbie,

Thanks for quick reply. I tried your method but I get a vertical image totally black. To get the binary contour, I saved the ROI from the ROI Manager and applied it on a new black image created through MS Paint. Is the process okay?

Many Thanks,
kbimagej

Please use the binary contour Iâ€™ve provided and try with it.

Regards

Hebrie

I got the graph with your image. But I am getting a black vertical image when I use my binary contour. Is there a problem with the way I have generated the binary contour?

Many Thanks,
kbimagej

In this contribution
http://forum.image.sc/t/convert-variations-in-2-d-boundary-to-1-d/9829/9?u=herbie
Iâ€™ve provided the binary contour image from which I get the polar transform shown earlier.

binary contour image.

Regards

Herbie

with the selection is open in ImageJ.

In this case you can run the following macro to get the binary contour image:

``````orig = getImageID;
setForegroundColor( 255, 255, 255 );
newImage( "BinaryContour", "8-bit black", getWidth(), getHeight(), 1 );
run( "Restore Selection" );
run( "Draw", "slice" );
run( "Select None" );
selectImage( orig );
close();
``````

Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it.

HTH

Herbie

@anon96376101

Works like a charm. One last question though. I would like to find the number variations i.e. no. of local maximas and minimas. Any idea on this? I tried using Analyze Line Graph (Analyze -> Tools ->Analyze Line Graph). But it didnâ€™t give me any result.

Many Thanks,
kbimagej

I would like to find the number variations i.e. no. of local maximas and minimas.

This depends on what you regard as relative extrema. A tolerance value must be defined to give you these numbers. Have a look at
https://imagej.nih.gov/ij/developer/macro/functions.html
and especially:

``````Array.findMaxima(array, tolerance);
Array.findMinima(array, tolerance);
``````

Now itâ€™s time to learn macro coding â€¦
https://imagej.nih.gov/ij/developer/macro/macros.html

Regards

Herbie

just an add to the suggestion of @anon96376101 to use the macro and findMaxima method, you can also take a look to this FindPeaks tool (https://imagej.net/Find_Peaks) in the BAR (https://imagej.net/BAR) plugins collection

Finally here is an ImageJ macro that gives you all of the desired values of a closed contour image and saves the polar transform data to disk:

``````// imagej-macro "maximum height" (Herbie G., 15. March 2018)
requires( "1.51w" );
nme = "Polar_Transformer.class";
if ( !File.exists( getDirectory( "plugins" ) + nme ) ) exit( "Macro requires PlugIn \"" + nme + "\" !" );
if ( nImages != 1 )  exit( "A single contour image must be open!" );
run( "8-bit" );
run( "Make Binary" );
orig = getImageID();
nme = split( getTitle(), "." );
tol = 18;
a = newArray( "Center of Mass", "Center of fitting Circle" );
Dialog.create( "Polar Transformation" );
Dialog.addNumber( "Tolerance", tol, 0, 2, "" );
Dialog.show();
method = Dialog.getChoice();
tol = 10 * round( Dialog.getNumber() );
if ( method == a[0] ) {
List.setMeasurements;
x = List.getValue( "XM" );
y = List.getValue( "YM" );
nme = nme[0] + "_CoM.csv";
} else {
selectLine();
run( "Fit Circle" );
getSelectionBounds( x, y, w, h );
x += w * 0.5;
y += h * 0.5;
run( "Select None" );
nme = nme[0] + "_CoC.csv";
}
path = getDirectory( "Where to save the results?" ) + nme;
setBatchMode( true );
getRawStatistics( n, mn );
n *= mn / 255;
run( "Polar Transformer", "method=Polar degrees=360 number=[n] center_x=[x] center_y=[y]" );
run( "Make Binary" );
run( "Skeletonize" );
selectLine();
run( "Save XY Coordinates...", "save=[" + path + "]" );
open( path );
a = newArray( nResults );
selectWindow( "Results" );
for ( i=0; i < nResults; i++ ) a[i] = getResult( "X", i );
run( "Close" );
Array.getStatistics( a, mi, mx, mn, std );
print( method + ":  x = " + d2s( x, 2 ) + "; y = " + d2s( y, 2 ) + ";" );
print( "Mean radius = " + d2s( mn, 2 ) + fromCharCode( 177 ) + d2s( std, 2 ) + " pixel;" );
print( "( min = " + mi + "; max = " + mx + "; )" );
tol = round( tol / ( mx - mi ) );
relMx = Array.findMaxima( a, tol );
print( "Tolerance = " +  tol + ":  relMin = " + (relMx.length-1) + "; relMax = " + relMx.length + ";"  );
selectImage( orig );
run("Revert");
setBatchMode( false );
exit();
function selectLine() {
yPos = getHeight() * 0.5;
makeRectangle( 0, yPos, getWidth(), 1 );
p = getProfile();
p = Array.findMaxima( p, 0 );
Array.reverse( p );
doWand( p[0], yPos );
}
// imagej-macro "maximum height" (Herbie G., 15. March 2018)
``````

HTH

Herbie

1 Like