Get continuous pixel coordinates from a line ROI

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Get continuous pixel coordinates from a line ROI

lechristophe
Dear all,

I know this subject has been discussed before, but I couldn't find a
good answer to this problem. I'm working on a macro tool  that will
replicate the "Straigthen" plugin
(http://rsbweb.nih.gov/ij/plugins/straighten.html). The macro starts
with a spline fitting of the line ROI, then retrieve all the ROI
coordinates using getSelectionCoordinates(). Unfortunately, this
function only returns vertices, and not all pixel coordinates
(continuous) along the ROI. Before implementing a loop to interpolate
the missing points between vertices, I wanted to ask if someone has a
more elegant solution...

Thanks a lot,

Christophe
Reply | Threaded
Open this post in threaded view
|

Re: Get continuous pixel coordinates from a line ROI

Gabriel Landini
On Saturday 12 July 2008, Christophe Leterrier wrote:
> The macro starts with a spline fitting of the line ROI, then retrieve all
> the ROI > coordinates using getSelectionCoordinates().
> Unfortunately, this  function only returns vertices, and not all pixel
> coordinates (continuous) along the ROI. Before implementing a loop to
> interpolate the missing points between vertices, I wanted to ask if someone
> has a more elegant solution...

Not elegant... but just in case:

execute in the macro "waitforuser" so it stops and you can draw the line,

Draw the line ROI on the image with the mouse

now the macro continues:
Set batchmode true (to make the following transparent),
Duplicate the image,
Math subtract 1,
Set foreground colour to 255,
Restore selection,
Fit spline,
Draw,
now scan the image for pixels == 255 and store in an array.
You can get the array size first by looking at the image histogram (as the
only 255 pixels will be the drawn spline).
close image (so the batch mode off does not show it).
set batch mode off

The drawback is that the line pixels are not in drawn order.


BTW, the Align_RGB_planes plugin mentioned yesterday is updated at my site.

Cheers,

G.
Reply | Threaded
Open this post in threaded view
|

Re: Get continuous pixel coordinates from a line ROI

lechristophe
In reply to this post by lechristophe
I modified a macro proposed by Michael Cammer that was quite
complicated (http://www.nabble.com/Re%3A-List-all-pixel-coordinates-in-ROI-p529148.html).
Thanks to Chris Coulon who proposed a slightly different strategy,
that is just get the distance between each vertices and increment with
subpixel distance between these two points, I managed to get a simpler
second version wich I append here :

https://www.bio.espci.fr/upload/files/All_Coordinates.txt

Hope it will be usefull for others,

Christophe Leterrier


On Sat, Jul 12, 2008 at 15:52, Christophe Leterrier
<[hidden email]> wrote:

> Dear all,
>
> I know this subject has been discussed before, but I couldn't find a
> good answer to this problem. I'm working on a macro tool  that will
> replicate the "Straigthen" plugin
> (http://rsbweb.nih.gov/ij/plugins/straighten.html). The macro starts
> with a spline fitting of the line ROI, then retrieve all the ROI
> coordinates using getSelectionCoordinates(). Unfortunately, this
> function only returns vertices, and not all pixel coordinates
> (continuous) along the ROI. Before implementing a loop to interpolate
> the missing points between vertices, I wanted to ask if someone has a
> more elegant solution...
>
> Thanks a lot,
>
> Christophe
>
Reply | Threaded
Open this post in threaded view
|

Re: Get continuous pixel coordinates from a line ROI

Gabriel Landini
On Saturday 12 July 2008, Christophe Leterrier wrote:

> I modified a macro proposed by Michael Cammer that was quite
> complicated
> (http://www.nabble.com/Re%3A-List-all-pixel-coordinates-in-ROI-p529148.html
>). Thanks to Chris Coulon who proposed a slightly different strategy, that
> is just get the distance between each vertices and increment with subpixel
> distance between these two points, I managed to get a simpler second
> version wich I append here :
>
> https://www.bio.espci.fr/upload/files/All_Coordinates.txt
>
> Hope it will be usefull for others,

I am not sure the reason, but I think this may not be working as intended:
1. the line it gets shorter by 1 each time the macro runs,
2. for diagonal lines, some points are repeated (usually the 2nd point from
the start is 2 points overlapping rather than 1).

Can anybody confirm this? It is easier to try this with short lines and the
image zoomed in).
Cheers

Gabriel
Reply | Threaded
Open this post in threaded view
|

Re: Get continuous pixel coordinates from a line ROI

lechristophe
Damn, you're right !
For the shrinking line, the problem was that the macro doesn't handle
the last point (corrected).
For the duplicate points, I had to revert to Michael strategy
(although I'll also try just to add a test for creation of the same
point for Chris strategy). The new version is here :

https://www.bio.espci.fr/upload/files/All_Coordinates2.txt



Christophe


On Sun, Jul 13, 2008 at 11:40, Gabriel Landini <[hidden email]> wrote:

> On Saturday 12 July 2008, Christophe Leterrier wrote:
>> I modified a macro proposed by Michael Cammer that was quite
>> complicated
>> (http://www.nabble.com/Re%3A-List-all-pixel-coordinates-in-ROI-p529148.html
>>). Thanks to Chris Coulon who proposed a slightly different strategy, that
>> is just get the distance between each vertices and increment with subpixel
>> distance between these two points, I managed to get a simpler second
>> version wich I append here :
>>
>> https://www.bio.espci.fr/upload/files/All_Coordinates.txt
>>
>> Hope it will be usefull for others,
>
> I am not sure the reason, but I think this may not be working as intended:
> 1. the line it gets shorter by 1 each time the macro runs,
> 2. for diagonal lines, some points are repeated (usually the 2nd point from
> the start is 2 points overlapping rather than 1).
>
> Can anybody confirm this? It is easier to try this with short lines and the
> image zoomed in).
> Cheers
>
> Gabriel
>
Reply | Threaded
Open this post in threaded view
|

Re: Get continuous pixel coordinates from a line ROI

Gabriel Landini
In reply to this post by Gabriel Landini
More on this problem.
If I fit a spline, and then run:

getSelectionCoordinates(x, y);
for (i=0;i<x.length;i++)
 print (x[i], y[i]);

I get lots of the same pixel coordinates which I guesss is because the spline
is subsampled.

Here is my previous suggestion which returns the coordinates (only once) of
the pixels under the selection:



//==============================================
//getSplineCoordinates.txt
//
waitForUser("Draw a polyline and press OK,\nthen I will fit a spline\nand get
the coordinates");

if(selectionType()!=6) {
   exit("Not a polyline selection!");
}

run("Fit Spline");

setBatchMode(true);
w=getWidth();
h=getHeight();
newImage("temp", "8-bit Black", w, h, 1);
run("Restore Selection");
run("Colors...", "foreground=white background=black selection=yellow");
run("Draw");
nBins = 256;
getHistogram(values, counts, nBins);
x=newArray(counts[255]);
y=newArray(counts[255]);

counter=-1;
for (j=0;j<h;j++){
 for (i=0;i<w;i++){
   if (getPixel(i,j)==255){
    counter++;
    x[counter]=i;
    y[counter]=j;
    print(x[counter],y[counter]);
   }
 }
}
close();
setBatchMode(false);
//==============================================
Reply | Threaded
Open this post in threaded view
|

Re: Get continuous pixel coordinates from a line ROI

Christopher Coulon-2
In reply to this post by lechristophe
Here¹s a macro and plugin that give the complete coordinates of a polygon
selection (closed or line).

Chris Coulon
       

The GAIA Group
 Global Automated Image Analysis

We help Researchers help themselves!
Find out about Online Tutoring for ImageJ

Christopher Coulon, Ph.D., Founder
http://gaiag.net
[hidden email]



macro "Get all line coordinates [f1]" {
    sum = 0;
    count = 0;
   
    getSelectionCoordinates(x, y);
    len = x.length;
    x1 = newArray(len);
    y1 = newArray(len);
    hypot = newArray(len);
   
    //print("\n**********\ni x[i] y[i] x1[i] y1[i] hypot");
    for (i = 1; i < len; i++) {
        x1[i] = x[i-1] - x[i];
        y1[i] = y[i-1] - y[i];
         hypot[i] = sqrt(x1[i] * x1[i] + y1[i] * y1[i]);
         sum += hypot[i];
         //print(i + " " + x[i] + "  " + y[i] + " " + x1[i] + " " + y1[i] +
" " + hypot[i]);
    }
   
    fullPerimX = newArray(sum);
    fullPerimY = newArray(sum);

    for (i = 0; i < len; i++) {
        if(x1[i] != 0) {
            n = x1[i];
                   
            if(n < 0) {
                for(j = n; j < 0; j++) {
                    fullPerimX[count] = x[i] + j;
                    fullPerimY[count] = y[i];
                    count++;
                }
            }
            else {
                for(j = n; j > 0; j--) {
                    fullPerimX[count] = x[i] + j;
                    fullPerimY[count] = y[i];
                    count++;
                }
            }
        }
        else {
            if(y1[i] != 0) {
                n = y1[i];
               
                if(n < 0) {
                    for(j = n; j < 0; j++) {
                        fullPerimY[count] = y[i] + j;
                        fullPerimX[count] = x[i];
                        count++;
                    }
                }
                else {
                    for(j = n; j > 0; j--) {
                        fullPerimY[count] = y[i] + j;
                        fullPerimX[count] = x[i];
                        count++;
                    }
                }
            }
        }
    }
   
    print("\ncount = " + count + "\n***** Full Line Coordinates *****\n");
    print("Position     X     Y");
    for (i = 0; i < count; i++) {
        if(i < 10)
            print("    " + i + "          " + fullPerimX[i] + "   " +
fullPerimY[i]);
            else
            if(i < 100)
                print("  " + i + "          " + fullPerimX[i] + "   " +
fullPerimY[i]);
                else
                    print(" " + i + "          " + fullPerimX[i] + "   " +
fullPerimY[i]);
    }
   
}

import ij.IJ;
import ij.ImagePlus;
import ij.WindowManager;
import ij.gui.PolygonRoi;
import ij.gui.Roi;
import ij.measure.Calibration;
import ij.plugin.PlugIn;
import java.awt.Rectangle;

/**
 * © 2008 The GAIA Group
 * Christopher Coulon, PhD
 * http://gaiag.net
 */

public class A_Line_Roi implements PlugIn
{

    public void run(String arg0)
    {
        if(WindowManager.getImageCount() < 1)
        {
            IJ.error("No Images Open!");
            return;
        } // if count < 1
       
        ImagePlus imp = WindowManager.getCurrentImage();
               
        Calibration cal = imp.getCalibration();
        double pixW = cal.pixelWidth;
        double pixH = cal.pixelHeight;
       
        int len = 0;
        int sum = 0;
        int counter = 0;
        int n = 1;
       
        Roi line = imp.getRoi();
       
        if(line == null)
        {
            IJ.error("No Polygon Selection!");
            return;
        } // if line
       
        Rectangle bounds = line.getBounds();
       
        int xBound = bounds.x;
        int yBound = bounds.y;
               
        if(line instanceof PolygonRoi)
        {
            PolygonRoi proi = (PolygonRoi)line;
            len = proi.getNCoordinates();
           
            int[] hypot = new int[len];
            int[] x1 = new int[len];
            int[] y1 = new int[len];
           
            int[] xCoords = proi.getXCoordinates();
            double[] xProi = new double[len];
            int[] yCoords = proi.getYCoordinates();
            double[] yProi = new double[len];
           
            for (int i = 0; i < len; i++) {
                xProi[i] = pixW*xCoords[i] + xBound;
                yProi[i] = pixH*yCoords[i] + yBound;
                if(i > 0)
                {
                    x1[i] = (int) (xProi[i - 1] - xProi[i]);
                    y1[i] = (int) (yProi[i - 1] - yProi[i]);
                    hypot[i] = (int) Math.sqrt(x1[i] * x1[i] + y1[i] *
y1[i]);
                    sum += hypot[i];
                } // if i
               
            } // for i

            int[] fullPerimX = new int[sum];
            int[] fullPerimY = new int[sum];

            for (int i = 0; i < len; i++)
            {
               
                if(x1[i] != 0)
                {
                    n = x1[i];
                    if(n < 0)
                    {
                        for(int j = n; j < 0; j++)
                        {
                            fullPerimX[counter] = xCoords[i] + j + xBound;
                            fullPerimY[counter] = yCoords[i] + yBound;
                            counter++;
                        } // for j
                    } // if n
                    else
                    {
                        for(int j = n; j > 0; j--)
                        {
                            fullPerimX[counter] = xCoords[i] + j + xBound;
                            fullPerimY[counter] = yCoords[i] + yBound;
                            counter++;
                        } // for j
                    } // else
                } // if x1
                else
                {
                    if(y1[i] != 0)
                    {
                        n = y1[i];
                        if(n < 0)
                        {
                            for(int j = n; j < 0; j++)
                            {
                                fullPerimY[counter] = yCoords[i] + j +
yBound;
                                fullPerimX[counter] = xCoords[i] + xBound;
                                counter++;
                            } // for j
                        } // if n
                        else
                        {
                            for(int j = n; j > 0; j--)
                            {
                                fullPerimY[counter] = yCoords[i] + j +
yBound;
                                fullPerimX[counter] = xCoords[i] + xBound;
                                counter++;
                            } // for j
                        } // else
                    } // if y1
                } // else
            } // for i

            IJ.log("**** Full Line Coordinates ****\n" +
                    "\nPosition    X     Y\n");
            for (int i = 0; i < sum; i++)
            {
                if(i < 10)
                    IJ.log("      " + i + "       " +
                        fullPerimX[i] +
                        "     " + fullPerimY[i]);
                else
                    if(i < 100)
                        IJ.log("    " + i + "        " +
                            fullPerimX[i] +
                            "     " + fullPerimY[i]);
                    else
                        IJ.log("   " + i + "        " +
                            fullPerimX[i] +
                            "     " + fullPerimY[i]);
            } // for i
        } // if roi

        else
        {
            IJ.showMessage("Only Polygon ROIs are processed");
            return;
        } // else  
       
    } // run method

} // A_Line_Roi class


>
> Damn, you're right !
> For the shrinking line, the problem was that the macro doesn't handle
> the last point (corrected).
> For the duplicate points, I had to revert to Michael strategy
> (although I'll also try just to add a test for creation of the same
> point for Chris strategy). The new version is here :
>
> https://www.bio.espci.fr/upload/files/All_Coordinates2.txt
>
>
>
> Christophe
>
>
> On Sun, Jul 13, 2008 at 11:40, Gabriel Landini <[hidden email]> wrote:
>> > On Saturday 12 July 2008, Christophe Leterrier wrote:
>>> >> I modified a macro proposed by Michael Cammer that was quite
>>> >> complicated
>>> >>
>>> (http://www.nabble.com/Re%3A-List-all-pixel-coordinates-in-ROI-p529148.html
>>> >>). Thanks to Chris Coulon who proposed a slightly different strategy, that
>>> >> is just get the distance between each vertices and increment with
>>> subpixel
>>> >> distance between these two points, I managed to get a simpler second
>>> >> version wich I append here :
>>> >>
>>> >> https://www.bio.espci.fr/upload/files/All_Coordinates.txt
>>> >>
>>> >> Hope it will be usefull for others,
>> >
>> > I am not sure the reason, but I think this may not be working as intended:
>> > 1. the line it gets shorter by 1 each time the macro runs,
>> > 2. for diagonal lines, some points are repeated (usually the 2nd point from
>> > the start is 2 points overlapping rather than 1).
>> >
>> > Can anybody confirm this? It is easier to try this with short lines and the
>> > image zoomed in).
>> > Cheers
>> >
>> > Gabriel
>> >
Reply | Threaded
Open this post in threaded view
|

Re: Get continuous pixel coordinates from a line ROI

lechristophe
In reply to this post by Gabriel Landini
The problem with your strategy (your macro) is that it does not store
the ROI coordinates processively (i.e. in order along the path from
first to lat point), but as a x-y scan intersecting with the ROI. And
this is what I need to then trace perpendicular segments, in order to
store profiles that will be used to reconstruct the straightened image
(because at the beginning I want to reprogram the Straighten plugin as
a macro tool).

On Sun, Jul 13, 2008 at 13:27, Gabriel Landini <[hidden email]> wrote:

> More on this problem.
> If I fit a spline, and then run:
>
> getSelectionCoordinates(x, y);
> for (i=0;i<x.length;i++)
>  print (x[i], y[i]);
>
> I get lots of the same pixel coordinates which I guesss is because the spline
> is subsampled.
>
> Here is my previous suggestion which returns the coordinates (only once) of
> the pixels under the selection:
>
>
>
> //==============================================
> //getSplineCoordinates.txt
> //
> waitForUser("Draw a polyline and press OK,\nthen I will fit a spline\nand get
> the coordinates");
>
> if(selectionType()!=6) {
>   exit("Not a polyline selection!");
> }
>
> run("Fit Spline");
>
> setBatchMode(true);
> w=getWidth();
> h=getHeight();
> newImage("temp", "8-bit Black", w, h, 1);
> run("Restore Selection");
> run("Colors...", "foreground=white background=black selection=yellow");
> run("Draw");
> nBins = 256;
> getHistogram(values, counts, nBins);
> x=newArray(counts[255]);
> y=newArray(counts[255]);
>
> counter=-1;
> for (j=0;j<h;j++){
>  for (i=0;i<w;i++){
>   if (getPixel(i,j)==255){
>    counter++;
>    x[counter]=i;
>    y[counter]=j;
>    print(x[counter],y[counter]);
>   }
>  }
> }
> close();
> setBatchMode(false);
> //==============================================
>
Reply | Threaded
Open this post in threaded view
|

Re: Get continuous pixel coordinates from a line ROI

Wayne Rasband
In reply to this post by lechristophe
> The problem with your strategy (your macro) is that it does not store
> the ROI coordinates processively (i.e. in order along the path from
> first to lat point), but as a x-y scan intersecting with the ROI. And
> this is what I need to then trace perpendicular segments, in order to
> store profiles that will be used to reconstruct the straightened image
> (because at the beginning I want to reprogram the Straighten plugin as
> a macro tool).

ImageJ 1.41h will have an easy way to get the coordinates of points
along a line, spaced one pixel apart. This feature is not yet in the
v1.41h daily build but it does have the ability to display wide lines
using translucency, similar to the way the Straighten plugin works.

-wayne

>
> On Sun, Jul 13, 2008 at 13:27, Gabriel Landini <[hidden email]>
> wrote:
> > More on this problem.
> > If I fit a spline, and then run:
> >
> > getSelectionCoordinates(x, y);
> > for (i=0;i<x.length;i++)
> >  print (x[i], y[i]);
> >
> > I get lots of the same pixel coordinates which I guesss is because
> the spline
> > is subsampled.
> >
> > Here is my previous suggestion which returns the coordinates (only
> once) of
> > the pixels under the selection:
> >
> >
> >
> > //==============================================
> > //getSplineCoordinates.txt
> > //
> > waitForUser("Draw a polyline and press OK,\nthen I will fit a
> spline\nand get
> > the coordinates");
> >
> > if(selectionType()!=6) {
> >   exit("Not a polyline selection!");
> > }
> >
> > run("Fit Spline");
> >
> > setBatchMode(true);
> > w=getWidth();
> > h=getHeight();
> > newImage("temp", "8-bit Black", w, h, 1);
> > run("Restore Selection");
> > run("Colors...", "foreground=white background=black
> selection=yellow");
> > run("Draw");
> > nBins = 256;
> > getHistogram(values, counts, nBins);
> > x=newArray(counts[255]);
> > y=newArray(counts[255]);
> >
> > counter=-1;
> > for (j=0;j<h;j++){
> >  for (i=0;i<w;i++){
> >   if (getPixel(i,j)==255){
> >    counter++;
> >    x[counter]=i;
> >    y[counter]=j;
> >    print(x[counter],y[counter]);
> >   }
> >  }
> > }
> > close();
> > setBatchMode(false);
> > //==============================================
> >
>
Reply | Threaded
Open this post in threaded view
|

run-once plugin?

GeraldT
In reply to this post by lechristophe
Hi everybody,

I have written a plugin to do some dental measurements on X-rays. The plugin is uses the PlugInFrame interface
and opens a menu in a new frame. It starts every time if called from the compile and run-command. I have installed the plugin with shortcut F5 and a command. After starting ImageJ I can run the plugin once by pressing F5 or using the Plugins-menu, but after the plugin is stopped it won't start again until ImageJ is restarted. I cannot find the reason for this behavior.
The program is ended by the close() command. Can anybody help me?

I will release the plugin to public domain later if it proves useful, but still the code is to messy to publish it.

Mvh


Gerald R. Torgersen
IT-seksjonen,
Det odontologiske fakultet / Faculty of Dentistry
Universitetet i Oslo / University of Oslo
Reply | Threaded
Open this post in threaded view
|

Re: run-once plugin?

Michael Schmid
Hi Gerald,

sometimes plugins cause the shortcuts not to work - especially if  
they register as keyListeners to ImageJ and don't de-register. Can  
you run the plugin from the Plugins Menu?
If you can't run it from the Plugins menu, maybe you have some static  
variables that prevent it from running again?

In the constructor, your first statement should probably be something  
like
   super("title of my plugin");
but I think that omitting it would not cause your problem.

close() at the end is fine; you may also want to add a
    public void windowClosing(WindowEvent e) { close(); }
method in case someone closes it via the 'close' box of the window.  
Funny enough, this is missing in PlugInFrame.windowClosing.


Michael
________________________________________________________________

On 3 Jun 2010, at 16:31, Gerald Ruiner Torgersen wrote:

> Hi everybody,
>
> I have written a plugin to do some dental measurements on X-rays.  
> The plugin is uses the PlugInFrame interface
> and opens a menu in a new frame. It starts every time if called  
> from the compile and run-command. I have installed the plugin with  
> shortcut F5 and a command. After starting ImageJ I can run the  
> plugin once by pressing F5 or using the Plugins-menu, but after the  
> plugin is stopped it won't start again until ImageJ is restarted. I  
> cannot find the reason for this behavior.
> The program is ended by the close() command. Can anybody help me?
>
> I will release the plugin to public domain later if it proves  
> useful, but still the code is to messy to publish it.
>
> Mvh
>
>
> Gerald R. Torgersen
> IT-seksjonen,
> Det odontologiske fakultet / Faculty of Dentistry
> Universitetet i Oslo / University of Oslo
Reply | Threaded
Open this post in threaded view
|

Re: run-once plugin?

GeraldT
Hello Michael,

thank you for your answer. I have already solved the problem thanks to a mail I got.
The problem was that one variable was declared static. I removed the static and everything works well.

And sorry, everybody for posting this under the wrong tread, long time since I posted to the list.

Regards Gerald