Automatically create multi points

Hey,

I have multiple graphs from which I want to extract the coordinates so I can import them into Excel etc. The graphs are all just one thick black line as in the picture. Up until now I manually put multi points on the graph and then Save As → X-Y Coordinates. It looks like this:

It works but of course is not very accurate and tedious.
Furthermore, for better comparibility I would like to have one pair of coordinate for every (or e.g. every 2nd) pixel in X direction, which is hard (impossible) to do manually.

Any help how to automate this in a macro would be highly appreciated!

Hi @dev3011

run("Set Measurements...", "area mean display scientific add redirect=None decimal=2");
newImage("Untitled", "8-bit white", 512, 512, 1);
msg = "You have to draw a curve! Then click OK";
title="Warning!";
waitForUser(title, msg);
run("Interpolate", "interval=1");

getSelectionCoordinates(x, y);
for (i=0; i<x.length; i++)
     print(i+" "+x[i]+" "+y[i]);
Array.show( "Selection Coordinates", x, y );

Please tell me if this helps
Thank you

1 Like

Hi Mathew,

thanks a lot for your reply! Getting the coordinates works very well with your macro.
With this solution I have to draw a curve myself, right? For my purposes I would need imageJ to find the black curve automatically and then give me the coordinates for this curve. Would that also be possible?

1 Like

@dev3011
Please send an unannotated image; Please

This is one of the original images I would have to read in.

This would be another one:

1 Like

@dev3011
With your first image.
There are probably simpler ones, but I’m a bit tired …
Other readers will surely have better. Thank you in advance to them.

run("Duplicate...", " ");
run("8-bit");
setAutoThreshold("Default");
//run("Threshold...");
//setThreshold(0, 107);
setOption("BlackBackground", true);
run("Convert to Mask");
run("Erode");
run("Skeletonize");
run("Ridge Detection", "line_width=10 high_contrast=230 low_contrast=87 correct_position show_junction_points add_to_manager method_for_overlap_resolution=NONE sigma=3.39 lower_threshold=0 upper_threshold=0.85 minimum_line_length=0 maximum=100000");
roiManager("Select", 1);
run("Interpolate", "interval=5 adjust");
getSelectionCoordinates(x, y);
for (i=0; i<x.length; i++)
     print(i+" "+x[i]+" "+y[i]);
Array.show( "Selection Coordinates", x, y );
1 Like

Thank you so much for the replay, @Mathew. In principal this works very well, however in two areas the graph is a bit off (the peak and the lowest point to the right):

I tried to change the parameters of the ridge detection, but haven’t found a way to improve it yet. Any idea on how to improve this?
Thanks again for the help!

/edit: Setting sigma=1 makes the ridge detection much better, but the selection is still off.

@dev3011
Test this:

macro "Automatically create multi points"
{
requires("1.53i");
setBackgroundColor(0,0,0);
setOption("BlackBackground",true);
orig=getImageID();
selectImage(orig);
h=getHeight();
l=getWidth();
//--------------------------------
newImage("temp-1", "8-bit white", l+100, h+100, 1);
newImage("temp-2", "8-bit white", l+100, h+100, 1);
selectImage(orig);
run("Select All");
run("Copy");
selectImage("temp-2");
run("Paste");
run("Select None");
setAutoThreshold("Default");
//run("Threshold...");
//setThreshold(0, 107);
setOption("BlackBackground", true);
run("Convert to Mask");
rename("Results.png");
run("Duplicate...", " ");
// Apply ridge detection
run("Ridge Detection", "line_width=10 high_contrast=230 low_contrast=87 correct_position show_junction_points add_to_manager method_for_overlap_resolution=NONE sigma=3.39 lower_threshold=0 upper_threshold=0.85 minimum_line_length=0 maximum=100000");
roiManager("Show All with labels");
waitForUser("Take into account the ROIs named C xyz.\nChoose the ROI of the line to interpolate.");
selectImage("temp-1");
run("Restore Selection");
run("Interpolate", "interval=5 adjust");
// Coordinates search
getSelectionCoordinates(x, y);
for (i=0; i<x.length; i++) 
     print(i+" "+x[i]+" "+y[i]);
Array.show( "Selection Coordinates", x, y );
close("Log");
selectWindow("Results.png");
run("Restore Selection");
close("ROI Manager");
close("\\Others");
//--------------------------------
exit("All is done !");
}

1 Like

Thank you, @Mathew .It looks awesome, but I don’t really know how to use it I think. Which ROIs do I have to choose? Until the waitForUser all goes well, but then when I don’t choose an ROI I get this:


If I choose an ROI I only get a single point.
Thank you so much for your time!

  1. On the black image:
    Question: What part are you interested in?
    Answer: C115
  2. On ROI manager: select C115
    3: click on OK

Did you read the message PM?

1 Like

Oh sorry, I didn’t see imagej highlights the line ROI when clicking on it… my bad.
This all looks great now in ImageJ, just when I import the coordinates to e.g. Excel they are very steep. Is this just matter of representation?
grafik

In addition, I want to multiply the y values of two given graphs. Thus, I would need y values at exactly the same x values for all graphs. The images are all of the same scale and size. I’ve tried to use the toScale() command, but that didn’t give me better results. Would that be possible?
Sorry that I am not of help myself. It is the first time I am using this type of analysis with imagej… Thank you for your patience!

In order to maybe make it a bit clearer: I would assume that with the interval=5 command for the interpolation I would get coordinates with a gap of 5 pixels in between. However, the gap highly fluctuates.