Example #1
0
 public MeshViewer(String title, ArrayList<Triangle> triangles, boolean culling) {
   super(title);
   enableCullling = culling;
   this.setSize(640, 480);
   ArrayList<PointND> edgePoints = new ArrayList<PointND>();
   for (Triangle t : triangles) {
     edgePoints.add(t.getA());
     edgePoints.add(t.getB());
     edgePoints.add(t.getC());
   }
   PointND center = DoublePrecisionPointUtil.getGeometricCenter(edgePoints);
   Translation translation = new Translation(center.getAbstractVector().negated());
   double max = 0;
   for (PointND p : edgePoints) {
     p.applyTransform(translation);
     for (int i = 0; i < 3; i++) {
       if (Math.abs(p.get(i)) > max) {
         max = Math.abs(p.get(i));
       }
     }
   }
   AffineTransform affineTransform =
       new AffineTransform(SimpleMatrix.I_3.dividedBy(max / 1.0), new SimpleVector(0, 0, 0));
   for (Triangle t : triangles) {
     t.applyTransform(translation);
     t.applyTransform(affineTransform);
   }
   this.triangles = triangles;
 }
  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;
  }
Example #3
0
  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;
  }
  public void setTrajectory(
      int numProjectionMatrices,
      double sourceToAxisDistance,
      double averageAngularIncrement,
      double detectorOffsetX,
      double detectorOffsetY,
      CameraAxisDirection uDirection,
      CameraAxisDirection vDirection,
      SimpleVector rotationAxis,
      PointND rotationCenter,
      double angleFirstProjection) {
    this.projectionMatrices = new Projection[numProjectionMatrices];
    this.primaryAngles = new double[numProjectionMatrices];
    this.numProjectionMatrices = numProjectionMatrices;
    this.sourceToAxisDistance = sourceToAxisDistance;
    this.averageAngularIncrement = averageAngularIncrement;
    this.detectorOffsetU = detectorOffsetX;
    this.detectorOffsetV = detectorOffsetY;

    double cosPhi = Math.cos(General.toRadians(angleFirstProjection));
    double sinPhi = Math.sin(General.toRadians(angleFirstProjection));
    SimpleMatrix rotMat = new SimpleMatrix(3, 3);
    rotMat.setElementValue(0, 0, cosPhi);
    rotMat.setElementValue(0, 1, sinPhi);
    rotMat.setElementValue(1, 0, -sinPhi);
    rotMat.setElementValue(1, 1, cosPhi);
    rotMat.setElementValue(2, 2, 1);
    SimpleVector centerToCameraIdealAtInitialAngle =
        SimpleOperators.multiply(rotMat, new SimpleVector(sourceToAxisDistance, 0, 0));
    Plane3D trajPlane =
        new Plane3D(
            rotationAxis,
            SimpleOperators.multiplyInnerProd(rotationAxis, rotationCenter.getAbstractVector()));
    double distToPlane = trajPlane.computeDistance(new PointND(centerToCameraIdealAtInitialAngle));
    SimpleVector centerToCameraDir =
        SimpleOperators.subtract(
            SimpleOperators.add(
                rotationAxis.multipliedBy(-1 * distToPlane), centerToCameraIdealAtInitialAngle),
            rotationCenter.getAbstractVector());
    centerToCameraDir.divideBy(centerToCameraDir.normL2());
    SimpleVector centerToCameraInitialInPlane =
        centerToCameraDir.multipliedBy(sourceToAxisDistance);

    for (int i = 0; i < numProjectionMatrices; i++) {
      primaryAngles[i] = i * averageAngularIncrement + angleFirstProjection;
      // System.out.println(primaryAngles[i] + " " + averageAngularIncrement + " " +
      // this.reconDimensions[0] + " " + this.reconDimensions[1]);
      projectionMatrices[i] = new Projection();
      double rotationAngle = General.toRadians(primaryAngles[i]);
      projectionMatrices[i].setRtFromCircularTrajectory(
          rotationCenter.getAbstractVector(),
          rotationAxis,
          sourceToAxisDistance,
          centerToCameraInitialInPlane,
          uDirection,
          vDirection,
          rotationAngle);
      SimpleVector spacingUV = new SimpleVector(pixelDimensionX, pixelDimensionY);
      SimpleVector sizeUV = new SimpleVector(detectorWidth, detectorHeight);
      SimpleVector offset = new SimpleVector(detectorOffsetX, detectorOffsetY);
      projectionMatrices[i].setKFromDistancesSpacingsSizeOffset(
          sourceToDetectorDistance, spacingUV, sizeUV, offset, 1.0, 0);
    }
    this.projectionStackSize = numProjectionMatrices;
    // System.out.println("Defined geometry with SDD " +sourceToDetectorDistance);
  }