package edu.stanford.rsl.tutorial; import ij.ImageJ; import edu.stanford.rsl.conrad.data.numeric.Grid2D; import edu.stanford.rsl.tutorial.fan.CosineFilter; import edu.stanford.rsl.tutorial.fan.FanBeamBackprojector2D; import edu.stanford.rsl.tutorial.fan.FanBeamProjector2D; import edu.stanford.rsl.tutorial.fan.redundancy.ParkerWeights; import edu.stanford.rsl.tutorial.filters.RamLakKernel; import edu.stanford.rsl.tutorial.parallel.ParallelBackprojector2D; import edu.stanford.rsl.tutorial.parallel.ParallelProjector2D; 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; public class FanBeamParallelBeamComparison { /** * @param args */ public static void main(String[] args) { // sinogram params double focalLength = 800, maxT = 300, deltaT = 1.0, gammaM = Math.atan((maxT / 2.f - 0.5) / focalLength), maxBeta = Math.PI + 2*gammaM, deltaBeta = maxBeta / 180; // image params int imgSzXMM = 200, // [mm] imgSzYMM = imgSzXMM; // [mm] float pxSzXMM = 1.0f, // [mm] pxSzYMM = pxSzXMM; // [mm] //float focalLength = 400, maxBeta = (float) Math.PI*2, deltaBeta = maxBeta / 200, maxT = 200, deltaT = 1; int phantomType = 2; // 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(); // image object 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.0, -(imgSzYGU * phantom.getSpacing()[1]) / 2.0); phantom.show(); Grid2D grid = phantom; // Fan Beam Projection FanBeamProjector2D fanBeamProjector = new FanBeamProjector2D(focalLength, maxBeta, deltaBeta, maxT, deltaT); Grid2D fanBeamSinoRay = fanBeamProjector.projectRayDriven(grid); fanBeamSinoRay.show("FB CL Sinogram"); // Parallel for comparison ParallelProjector2D Projector = new ParallelProjector2D(maxBeta, deltaBeta, maxT, deltaT); Grid2D pBeamSinoRay = Projector.projectRayDriven(grid); pBeamSinoRay.show("FB CL Sinogram"); // Parker Weights ParkerWeights pWeights = new ParkerWeights(focalLength, maxT, deltaT, maxBeta, deltaBeta); pWeights.show(); pWeights.applyToGrid(fanBeamSinoRay); fanBeamSinoRay.show("Fan Beam After Parker Weights"); // Cosine Weights CosineFilter cosFilt = new CosineFilter(focalLength, maxT, deltaT); // Filtering RamLakKernel ramLak = new RamLakKernel((int) (maxT / deltaT), deltaT); for (int theta = 0; theta < fanBeamSinoRay.getSize()[0]; ++theta) { cosFilt.applyToGrid(fanBeamSinoRay.getSubGrid(theta)); ramLak.applyToGrid(fanBeamSinoRay.getSubGrid(theta)); ramLak.applyToGrid(pBeamSinoRay.getSubGrid(theta)); } fanBeamSinoRay.show("Fan Beam Filtered Sinogram"); pBeamSinoRay.show("Parallel Beam Filtered Sinogram"); // Backproject fan beam FanBeamBackprojector2D fbp = new FanBeamBackprojector2D(focalLength, deltaT, deltaBeta, imgSzXMM, imgSzYMM); Grid2D fanbeamResult = fbp.backprojectPixelDriven(fanBeamSinoRay); fanbeamResult.show("Fan Beam Result"); // Backproject parallel beam ParallelBackprojector2D pbp = new ParallelBackprojector2D(imgSzXMM,imgSzYMM,pxSzXMM,pxSzYMM); Grid2D parallelResult = pbp.backprojectPixelDriven(pBeamSinoRay); parallelResult.show("Parallel Beam Result"); } } /* * Copyright (C) 2010-2014 Andreas Maier * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */