package edu.stanford.rsl.tutorial.fan; import ij.ImageJ; import edu.stanford.rsl.conrad.data.numeric.Grid2D; import edu.stanford.rsl.conrad.data.numeric.NumericGrid; import edu.stanford.rsl.conrad.data.numeric.NumericPointwiseOperators; import edu.stanford.rsl.tutorial.fan.FanBeamBackprojector2D; import edu.stanford.rsl.tutorial.fan.FanBeamProjector2D; import edu.stanford.rsl.tutorial.fan.redundancy.BinaryWeights; import edu.stanford.rsl.tutorial.fan.redundancy.CompensationWeights; import edu.stanford.rsl.tutorial.fan.redundancy.ParkerWeights; import edu.stanford.rsl.tutorial.fan.redundancy.SilverWeights; import edu.stanford.rsl.tutorial.filters.RamLakKernel; import edu.stanford.rsl.tutorial.phantoms.DotsGrid2D; import edu.stanford.rsl.tutorial.phantoms.MickeyMouseGrid2D; import edu.stanford.rsl.tutorial.phantoms.Phantom; import edu.stanford.rsl.tutorial.phantoms.TestObject1; import edu.stanford.rsl.tutorial.phantoms.UniformCircleGrid2D; /** * Simple example that computes and displays a reconstruction. * * @author Recopra Seminar Summer 2012 * */ public class FanBeamReconstructionExample { /** * @param args */ public static void main(String[] args) { // image params int imgSzXMM = 512, // [mm] imgSzYMM = imgSzXMM; // [mm] float pxSzXMM = 1.0f, // [mm] pxSzYMM = pxSzXMM; // [mm] // fan beam bp parameters double gammaM = 11.768288932020647*Math.PI/180, maxT = 500, deltaT = 1.0, focalLength = (maxT/2.0-0.5)*deltaT/Math.tan(gammaM), maxBeta = 285.95*Math.PI/180,//+gammaM*2, deltaBeta = maxBeta / 132; System.out.println(gammaM*180/Math.PI); int phantomType = 0; // 0 = circle, 1 = MickeyMouse, 2 = TestObject1, // 3=DotsGrid // size in grid units int imgSzXGU = (int) Math.floor(imgSzXMM / pxSzXMM), // [GU] imgSzYGU = (int) Math.floor(imgSzYMM / pxSzYMM); // [GU] new ImageJ(); FanBeamProjector2D fanBeamProjector = new FanBeamProjector2D( focalLength, maxBeta, deltaBeta, maxT, deltaT); Phantom phantom; switch (phantomType) { case 0: phantom = new UniformCircleGrid2D(imgSzXGU, imgSzYGU); break; case 1: phantom = new MickeyMouseGrid2D(imgSzXGU, imgSzYGU); break; case 2: phantom = new TestObject1(imgSzXGU, imgSzYGU); break; case 3: phantom = new DotsGrid2D(imgSzXGU, imgSzYGU); break; default: phantom = new UniformCircleGrid2D(imgSzXGU, imgSzYGU); break; } phantom.setSpacing(pxSzXMM, pxSzYMM); // origin is given in (negative) world coordinates phantom.setOrigin(-(imgSzXGU * phantom.getSpacing()[0]) / 2, -(imgSzYGU * phantom.getSpacing()[1]) / 2); //phantom.setOrigin(-50.0, -50.0); phantom.show(); Grid2D projectionP = new Grid2D(phantom); for (int iter =0; iter < 1; iter ++) { // create projections Grid2D fanBeamSinoRay = fanBeamProjector.projectRayDrivenCL(projectionP); fanBeamSinoRay.clone().show("Sinogram"); int weightType = 0; Grid2D RedundancyWeights; switch (weightType) { case 0: RedundancyWeights = new ParkerWeights(focalLength, maxT, deltaT, maxBeta, deltaBeta); break; case 1: RedundancyWeights = new SilverWeights(focalLength, maxT, deltaT, maxBeta, deltaBeta); break; case 2: RedundancyWeights = new CompensationWeights(focalLength, maxT, deltaT, maxBeta, deltaBeta); break; case 3: RedundancyWeights = new BinaryWeights(focalLength, maxT, deltaT, maxBeta, deltaBeta); break; default: RedundancyWeights = new CompensationWeights(focalLength, maxT, deltaT, maxBeta, deltaBeta); } RedundancyWeights.show("Current Weight"); NumericPointwiseOperators.multiplyBy(fanBeamSinoRay, RedundancyWeights); RamLakKernel ramLak = new RamLakKernel((int) (maxT / deltaT), deltaT); CosineFilter cKern = new CosineFilter(focalLength, maxT, deltaT); // Apply filtering for (int theta = 0; theta < fanBeamSinoRay.getSize()[1]; ++theta) { cKern.applyToGrid(fanBeamSinoRay.getSubGrid(theta)); } for (int theta = 0; theta < fanBeamSinoRay.getSize()[1]; ++theta) { ramLak.applyToGrid(fanBeamSinoRay.getSubGrid(theta)); } fanBeamSinoRay.show("After Filtering"); // Do the backprojection FanBeamBackprojector2D fbp = new FanBeamBackprojector2D(focalLength, deltaT, deltaBeta, imgSzXMM, imgSzYMM); Grid2D reco = fbp.backprojectPixelDrivenCL(fanBeamSinoRay); reco.show("Parker" + iter); NumericGrid recoDiff = NumericPointwiseOperators.subtractedBy(phantom, reco); recoDiff.show("RecoDiff" + iter); } } } /* * Copyright (C) 2010-2014 Andreas Maier * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */