Equal GridCells on Image!

I am new to ImageJ. I want to layout a 1cm^2 grid cell on 76x52 mm image. The grid in imageJ give grid not start from the corner of the image. It starts with half square. Any thoughts.

Thanks!

You can change and compile the original plugin here:

https://imagej.nih.gov/ij/plugins/grid.html

Eventually this plugin is helpful where the grid starts in the top-left (0,0) coordinate:

https://imagej.nih.gov/ij/plugins/graphic-overlay.html

Here is a slightly modified version (fast hacked) of the Grid plugin (called Grid2_) with an option to start at the 0,0 coordinate:

Source:

    import ij.*;
    import ij.process.*;
    import ij.gui.*;
    import java.awt.*;
    import java.awt.geom.*;
    import java.util.*;
    import ij.plugin.*;
    import ij.measure.*;

    public class Grid2_ implements PlugIn, DialogListener {
        private static double crossSize = 0.1;
        private static String[] colors = {"Red","Green","Blue","Magenta","Cyan","Yellow","Orange","Black","White"};
        private static String color = "Cyan";
        private final static int LINES=0, HLINES=1, CROSSES=2, POINTS=3, NONE=4;
        private static String[] types = {"Lines","Horizontal Lines", "Crosses", "Points", "None"};
        private static String type = types[LINES];
        private static double areaPerPoint;
        private static boolean randomOffset, startAtTopLeft;
        private static boolean bold;    
        private Random random = new Random(System.currentTimeMillis());
        private ImagePlus imp;
        private double tileWidth, tileHeight;
        private int xstart, ystart;
        private int linesV, linesH;
        private double pixelWidth=1.0, pixelHeight=1.0;
        private String units = "pixels";

        public void run(String arg) {
            imp = IJ.getImage();
            showDialog();
        }
            
        void drawPoints() {
            int one = 1;
            int two = 2;
            GeneralPath path = new GeneralPath();
            for(int h=0; h<linesV; h++) {
                for(int v=0; v<linesH; v++) {
                    float x = (float)(xstart+h*tileWidth);
                    float y = (float)(ystart+v*tileHeight);
                    path.moveTo(x-two, y-one); path.lineTo(x-two, y+one);
                    path.moveTo(x+two, y-one); path.lineTo(x+two, y+one);
                    path.moveTo(x-one, y-two); path.lineTo(x+one, y-two);
                    path.moveTo(x-one, y+two); path.lineTo(x+one, y+two);
                }
            }
            showGrid(path);
        }

        void drawCrosses() {
            GeneralPath path = new GeneralPath();
            float arm  = (int)Math.round(crossSize*tileWidth);
            if (arm<3) arm=3;
            for(int h=0; h<linesV; h++) {
                for(int v=0; v<linesH; v++) {
                    float x = (float)(xstart+h*tileWidth);
                    float y = (float)(ystart+v*tileHeight);
                    path.moveTo(x-arm, y);
                    path.lineTo(x+arm, y);
                    path.moveTo(x, y-arm);
                    path.lineTo(x, y+arm);
                }
            }
            showGrid(path);
        }

        void showGrid(Shape shape) {
            if (shape==null)
                imp.setOverlay(null);
            else {
                Roi roi = new ShapeRoi(shape);
                roi.setStrokeColor(getColor());
                if (bold && linesV*linesH<5000) {
                    ImageCanvas ic = imp.getCanvas();
                    double mag = ic!=null?ic.getMagnification():1.0;
                    double width = 2.0;
                    if (mag<1.0)
                        width = width/mag;
                    roi.setStrokeWidth(width);
                }
                imp.setOverlay(new Overlay(roi));
            }
        }

        void drawLines() {
            GeneralPath path = new GeneralPath();
            int width = imp.getWidth();
            int height = imp.getHeight();
            for(int i=0; i<linesV; i++) {
                float xoff = (float)(xstart+i*tileWidth);
                path.moveTo(xoff,0f);
                path.lineTo(xoff, height);
            }
            for(int i=0; i<linesH; i++) {
                float yoff = (float)(ystart+i*tileHeight);
                path.moveTo(0f, yoff);
                path.lineTo(width, yoff);
            }
            showGrid(path);
        }

        void drawHorizontalLines() {
            GeneralPath path = new GeneralPath();
            int width = imp.getWidth();
            int height = imp.getHeight();
            for(int i=0; i<linesH; i++) {
                float yoff = (float)(ystart+i*tileHeight);
                path.moveTo(0f, yoff);
                path.lineTo(width, yoff);
            }
            showGrid(path);
        }

        void showDialog() {
            int width = imp.getWidth();
            int height = imp.getHeight();
            Calibration cal = imp.getCalibration();
            int places;
            if (cal.scaled()) {
                pixelWidth = cal.pixelWidth;
                pixelHeight = cal.pixelHeight;
                units = cal.getUnits();
                places = 2;
            } else {
                pixelWidth = 1.0;
                pixelHeight = 1.0;
                units = "pixels";
                places = 0;
            }
            if (areaPerPoint==0.0)
                areaPerPoint = (width*cal.pixelWidth*height*cal.pixelHeight)/81.0; // default to 9x9 grid
            GenericDialog gd = new GenericDialog("Grid...");
            gd.addChoice("Grid type:", types, type);
            gd.addNumericField("Area per point:", areaPerPoint, places, 6, units+"^2");
            gd.addChoice("Color:", colors, color);
            gd.addCheckbox("Bold", bold);
            gd.addCheckbox("Random offset", randomOffset);
            gd.addCheckbox("Start at coordinate 0,0", startAtTopLeft);
            gd.addDialogListener(this);
            dialogItemChanged(gd, null);
            gd.showDialog();
            if (gd.wasCanceled()) 
                showGrid(null);
        }

        public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) {
            int width = imp.getWidth();
            int height = imp.getHeight();
            type = gd.getNextChoice();
            areaPerPoint = gd.getNextNumber();
            color = gd.getNextChoice();
            bold = gd.getNextBoolean();
            randomOffset = gd.getNextBoolean();
            startAtTopLeft = gd.getNextBoolean();
            double minArea= (width*height)/50000.0;
            if (type.equals(types[CROSSES])&&minArea<50.0)
                minArea = 50.0;
            else if (minArea<16)
                minArea = 16.0;
            if (areaPerPoint/(pixelWidth*pixelHeight)<minArea) {
                String err = "\"Area per Point\" too small";
                if (gd.wasOKed())
                    IJ.error("Grid", err);
                else
                    IJ.showStatus(err);
                return true;
            }
            double tileSize = Math.sqrt(areaPerPoint);
            tileWidth = tileSize/pixelWidth;
            tileHeight = tileSize/pixelHeight;
            if (randomOffset) {
                xstart = (int)(random.nextDouble()*tileWidth);
                ystart = (int)(random.nextDouble()*tileHeight);
            } 
            else if(startAtTopLeft){
                xstart = 0;
                ystart = 0;
            }
            
            else {
                xstart = (int)(tileWidth/2.0+0.5);
                ystart = (int)(tileHeight/2.0+0.5);
            }
            linesV = (int)((width-xstart)/tileWidth)+1; 
            linesH = (int)((height-ystart)/tileHeight)+1;
            if (gd.invalidNumber())
                return true;
            showGrid();
                return true;
        }

        private void showGrid() {
            if (type.equals(types[LINES]))
                drawLines();
            else if (type.equals(types[HLINES]))
                drawHorizontalLines();
            else if (type.equals(types[CROSSES]))
                drawCrosses();
            else  if (type.equals(types[POINTS]))
                drawPoints();
            else
                showGrid(null);
        }

        Color getColor() {
            Color c = Color.cyan;
            if (color.equals(colors[0])) c = Color.red;
            else if (color.equals(colors[1])) c = Color.green;
            else if (color.equals(colors[2])) c = Color.blue;
            else if (color.equals(colors[3])) c = Color.magenta;
            else if (color.equals(colors[4])) c = Color.cyan;
            else if (color.equals(colors[5])) c = Color.yellow;
            else if (color.equals(colors[6])) c = Color.orange;
            else if (color.equals(colors[7])) c = Color.black;
            else if (color.equals(colors[8])) c = Color.white;
            return c;
        }
    }
1 Like

Hi Bio7,
Thanks for modifying the code. I tried to use the code, however it gives me this message" undefined variable in line 1". Do I need to specify the image file?.

Thanks!

It is a Java plugin like the original.

So you have to save this file as Grid2_.java and compile it, see:


http://imagejdocu.tudor.lu/doku.php?id=howto:plugins:how_to_install_a_plugin

Hi Bio7,

I have some experience with ImageJ, but not experience with java. I included the grid plugin with one of my macros, but I want the grid to start at an specific selected point. In imageJ I was able to set the selected point as my 0,0 coordinate, however, the grid2 java app, always set it on the top left. I checked the code and I asume that I need to obtain the values from the image, and then set the as the x and y coordinates. How can I do it? Any help will be really appreciated.

Thanks

It just added an option to start the grid at the 0,0 coordinates in java.

else if(startAtTopLeft){
                xstart = 0;
                ystart = 0;
            }

You could change xstart, ystart with you selected coordinates (for instance set them from your macro code).