/** * constructor to create a view * * @param projection: projection image as Grid2D * @param radon: radon transformed and derived image as Grid2D * @param projMatrix: projection matrix as Projection */ public View(Grid2D projection, Grid2D radon, Projection projMatrix) { // Initialize center matrix // CENTER = new SimpleMatrix(3, 4); CENTER.setDiagValue(new SimpleVector(1.0, 1.0, 1.0)); // get data out of projection // this.projectionWidth = projection.getWidth(); this.projectionHeight = projection.getHeight(); // get data out of radon transformed image // this.radonWidth = radon.getWidth(); this.radonHeight = radon.getHeight(); this.projectionDiag = Math.sqrt(projectionWidth * projectionWidth + projectionHeight * projectionHeight); this.lineIncrement = radonWidth / projectionDiag; this.angleIncrement = radonHeight / Math.PI; // store radon transformed image // this.radon = radon; // get projection matrix P (3x4) // this.P = SimpleOperators.multiplyMatrixProd(projMatrix.getK(), CENTER); this.P = SimpleOperators.multiplyMatrixProd(this.P, projMatrix.getRt()); // get source position C (nullspace of the projection) // DecompositionSVD decoP = new DecompositionSVD(this.P); this.C = decoP.getV().getCol(3); // normalize source vectors by last component // // it is important that the last component is positive to have a positive center // as it is defined in oriented projective geometry this.C = this.C.dividedBy(this.C.getElement(3)); }
public Grid2D raytraceScene(PrioritizableScene phantomScene, Projection projection) { Trajectory geom = Configuration.getGlobalConfiguration().getGeometry(); // Grid2D slice = new Grid2D(geom.getDetectorWidth(), geom.getDetectorHeight()); Grid2D slice = detector.createDetectorGrid(geom.getDetectorWidth(), geom.getDetectorHeight(), projection); rayTracer.setScene(phantomScene); // Second rule of optimization is: Optimize later. PointND raySource = new PointND(0, 0, 0); raySource.setCoordinates(projection.computeCameraCenter()); StraightLine castLine = new StraightLine(raySource, new SimpleVector(0, 0, 0)); SimpleVector centerPixDir = null; if (accurate) { centerPixDir = projection.computePrincipalAxis(); } // SimpleVector prinpoint = trajectory.getProjectionMatrix(sliceNumber).getPrincipalPoint(); double xcorr = 0; // trajectory.getDetectorWidth()/2 - prinpoint.getElement(0); double ycorr = 0; // trajectory.getDetectorHeight()/2 - prinpoint.getElement(1); double length = trajectory.getSourceToDetectorDistance(); Edge environmentEdge = new Edge(new PointND(0), new PointND(length)); ArrayList<PhysicalObject> fallBackBackground = new ArrayList<PhysicalObject>(1); SimpleVector pixel = new SimpleVector(0, 0); boolean negate = false; for (int y = 0; y < trajectory.getDetectorHeight(); y++) { for (int x = 0; x < trajectory.getDetectorWidth(); x++) { pixel.setElementValue(0, x - xcorr); pixel.setElementValue(1, y - ycorr); SimpleVector dir = projection.computeRayDirection(pixel); if ((y == 0) && (x == 0)) { // Check that ray direction is towards origin. double max = 0; int index = 0; for (int i = 0; i < 3; i++) { if (Math.abs(dir.getElement(i)) > max) { max = Math.abs(dir.getElement(i)); index = i; } } double t = -raySource.get(index) / dir.getElement(index); if (t < 0) negate = true; } if (negate) dir.negate(); castLine.setDirection(dir); ArrayList<PhysicalObject> segments = rayTracer.castRay(castLine); if (accurate) { double dirCosine = SimpleOperators.multiplyInnerProd(centerPixDir, dir); length = trajectory.getSourceToDetectorDistance() / dirCosine; } if (segments == null) { fallBackBackground.clear(); segments = fallBackBackground; } else { if (accurate) { environmentEdge = new Edge(new PointND(0), new PointND(length - getTotalSegmentsLength(segments))); } } environment.setShape(environmentEdge); segments.add(environment); /* old code: double integral = absorptionModel.evaluateLineIntegral(segments); slice.putPixelValue(x, y, integral); */ detector.writeToDetector(slice, x, y, segments); } } return slice; }