Login  Register

Re: Get continuous pixel coordinates from a line ROI

Posted by Christopher Coulon-2 on Jul 15, 2008; 2:27am
URL: http://imagej.273.s1.nabble.com/Get-continuous-pixel-coordinates-from-a-line-ROI-tp3688036p3688047.html

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
>> >