package edu.stanford.rsl.tutorial.phantoms; import edu.stanford.rsl.conrad.data.numeric.Grid2D; import edu.stanford.rsl.conrad.utils.VisualizationUtil; import ij.ImageJ; import ij.ImagePlus; import ij.gui.PointRoi; /** * Creates an MTF phantom with five high density beads in a homogeneous cylinder * * @author Martin Berger * */ public class MTFphantom extends Phantom { private PointRoi[] beadCoords = null; /** * The constructor takes two arguments to initialize the grid. The cylinder * will be in the center and have a radius of r1% of the x-dimension. Thus * we recommend a grid size that is uniform in both directions. The outer beads * will be at a circle defined by radius of r2% of the r1 radius. * * @param x Size in X direction * @param y Size in Y direction * @param r1 Cylinder radius as a fraction of the X size * @param r2 Outer bead radius as a fraction of the cylinder radius * @param cylinderDensity Density value for the cylinder * @param beadDensity Density value for the beads * */ public MTFphantom(int x, int y, double r1, double r2, float cylinderDensity, float beadDensity) { super(x, y, "MTF Phantom - Bead Coordinates: (" + Integer.toString((x/2)-((int)Math.round(r1*r2*(double)x/2.0))) + "," + Integer.toString((y/2)) + "),(" + Integer.toString((x/2)) + "," + Integer.toString((y/2)) + "),(" + Integer.toString((x/2)+((int)Math.round(r1*r2*(double)x/2.0))) + "," + Integer.toString((y/2)) + "),(" + Integer.toString((x/2)) + "," + Integer.toString((y/2)+((int)Math.round(r1*r2*(double)x/2.0))) + "),(" + Integer.toString((x/2)) + "," + Integer.toString((y/2)-((int)Math.round(r1*r2*(double)x/2.0))) + ")"); int xcenter = x / 2; int ycenter = y / 2; int h1 = (int)Math.round(r1*r2*(double)x/2.0); beadCoords = new PointRoi[] {new PointRoi(xcenter-h1,ycenter), new PointRoi(xcenter,ycenter), new PointRoi(xcenter+h1,ycenter), new PointRoi(xcenter,ycenter+h1), new PointRoi(xcenter,ycenter-h1)}; // Create circle in the grid. double radius1 = r1 * (double)x/2.0; int beadRadius = (int)Math.round(r2*radius1); for (int i = -xcenter; i < -xcenter+x; i++) { for (int j = -ycenter; j < -ycenter+y; j++) { if (Math.pow(i, 2) + Math.pow(j, 2) <= (radius1 * radius1)) { if( (j == 0 && Math.abs(i) == beadRadius) || (i == 0 && Math.abs(j) == beadRadius) || (Math.pow(i,2) + Math.pow(j, 2) <= 0) ) { super.setAtIndex(i+xcenter, j+ycenter, beadDensity); } else { super.setAtIndex(i+xcenter, j+ycenter, cylinderDensity); } } else super.setAtIndex(i+xcenter, j+ycenter, 0.f); } } } public PointRoi[] getBeadPointsROI() { return this.beadCoords; } public static void main(String [] args) { new ImageJ(); MTFphantom test = new MTFphantom(1024, 1024, 0.95, 0.8, 1.f, 2.f); Grid2D phantom= new Grid2D(test); ImagePlus gi = VisualizationUtil.showGrid2D(phantom, test.getTitle()); ImagePlus ip = gi.duplicate(); ip.show(); ip.getProcessor().setRoi(test.getBeadPointsROI()[0]); } } /* * Copyright (C) 2010-2014 Martin Berger * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */