@Override public Grid2D applyToolToImage(Grid2D imageProcessor) throws Exception { Grid2D secondImageProcessor = imageProcessor; Grid2D firstImageProcessor = hardMaterial.getSubGrid(imageIndex); int xoffset = (firstImageProcessor.getWidth() - secondImageProcessor.getWidth()) / 2; int yoffset = (firstImageProcessor.getHeight() - secondImageProcessor.getHeight()) / 2; for (int i = 0; i < firstImageProcessor.getWidth(); i++) { for (int j = 0; j < firstImageProcessor.getHeight(); j++) { double value = slope * InterpolationOperators.interpolateLinear( firstImageProcessor, i + projectionXShift + xoffset, j + projectionYShift + yoffset); double value2 = secondImageProcessor.getPixelValue(i, j); double lambda = lambda0; try { if (value > 0.02) { lambda = lut.getValue(value2, value); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } secondImageProcessor.putPixelValue(i, j, value2 + (lambda0 - lambda) * value); } } return secondImageProcessor; }
/** * Method to calculate alpha and t as indices from the radon transformed image of a view. * Neccessary are the inverse projection image (as SimpleMatrix) and the epipolar plane E * * @param E: epipolar plane E as SimpleVector (4 entries) * @return: line integral value as double */ private double getValueByAlphaAndT(SimpleVector E) { // compute corresponding epipolar lines // // (epipolar lines are of 3x1 = 3x4 * 4x1) SimpleVector l_kappa = SimpleOperators.multiply(this.P_Inverse.transposed(), E); // init the coordinate shift // int t_u = this.projectionWidth / 2; int t_v = this.projectionHeight / 2; // compute angle alpha and distance to origin t // double l0 = l_kappa.getElement(0); double l1 = l_kappa.getElement(1); double l2 = l_kappa.getElement(2); double alpha_kappa_RAD = Math.atan2(-l0, l1) + Math.PI / 2; double t_kappa = -l2 / Math.sqrt(l0 * l0 + l1 * l1); // correct the coordinate shift // t_kappa -= t_u * Math.cos(alpha_kappa_RAD) + t_v * Math.sin(alpha_kappa_RAD); // correct some alpha falling out of the radon window // if (alpha_kappa_RAD < 0) { alpha_kappa_RAD *= -1.0; } else if (alpha_kappa_RAD > Math.PI) { alpha_kappa_RAD = 2.0 * Math.PI - alpha_kappa_RAD; } // write back to l_kappa // l_kappa.setElementValue(0, Math.cos(alpha_kappa_RAD)); l_kappa.setElementValue(1, Math.sin(alpha_kappa_RAD)); l_kappa.setElementValue(2, -t_kappa); // calculate x and y coordinates for derived radon transformed image // double x = t_kappa * this.lineIncrement + 0.5 * this.radonWidth; double y = alpha_kappa_RAD * this.angleIncrement; // get intensity value out of radon transformed image // // (interpolation needed) return InterpolationOperators.interpolateLinear(this.radon, x, y); }
public Grid2D createSinogramm(Grid2D phantom, boolean filter) { // Bouding Box Box imageBox = new Box( phantom.getWidth() * phantom.getSpacing()[0], phantom.getHeight() * phantom.getSpacing()[1], 2.0d); imageBox.setLowerCorner(new PointND(phantom.getOrigin()[0], phantom.getOrigin()[1], -1.0)); imageBox.setUpperCorner(new PointND(-phantom.getOrigin()[0], -phantom.getOrigin()[1], 1.0)); // walk over each projection for (int indexProjections = 0; indexProjections < projections; indexProjections++) { // walk along the detector for (int indexDetektor = 0; indexDetektor < numberPixel; indexDetektor++) { // define the parallel lines of the detector double[] indexWorld = this.indexToPhysical(indexDetektor, indexProjections); double angle = angleWidthR * indexProjections; double s = indexWorld[0]; double cos = Math.cos(angle); double sin = Math.sin(angle); PointND p1 = new PointND(cos * s, sin * s, 0.0d); PointND p2 = new PointND(cos * s - sin, sin * s + cos, 0.0d); StraightLine line = new StraightLine(p1, p2); // intersection of the box and the line ArrayList<PointND> crossingPoints = imageBox.intersect(line); // if there is no intersection -> change direction of the line and look again if (crossingPoints.size() == 0) { p2 = new PointND(cos * s + sin, sin * s - cos, 0.0d); line = new StraightLine(p1, p2); crossingPoints = imageBox.intersect(line); } if (crossingPoints.size() == 2) { PointND c1 = crossingPoints.get(0); PointND c2 = crossingPoints.get(1); // compute distance between intersectoin points double distance = c1.euclideanDistance(c2); // define the direction of the line double deltax = (c2.get(0) - c1.get(0)) / (distance); double deltay = (c2.get(1) - c1.get(1)) / (distance); double deltaz = (c2.get(2) - c1.get(2)) / (distance); PointND richtung = new PointND(deltax, deltay, deltaz); // result value at the current position in the sinogramm float val = 0.f; // stepsize of the integral double delta = 0.5; // in mm // line integral for (double k = 0; k < (distance); k = k + delta) { double indexX = c1.get(0) + k * (richtung.get(0)); double indexY = c1.get(1) + k * (richtung.get(1)); double[] indexImage = phantom.physicalToIndex(indexX, indexY); val += InterpolationOperators.interpolateLinear(phantom, indexImage[0], indexImage[1]); } this.setAtIndex(indexDetektor, indexProjections, (float) (val * delta)); } } } if (filter == true) { filtering(this); } Grid2D result = new Grid2D(this); return result; }