/** * Creates the meshes of one single phase and adds it to the ArrayList of 4D meshes. * * @param phase * @param parameters * @param info * @param splines */ private void createPhantom( int phase, double[] parameters, CONRADCardiacModelConfig info, ArrayList<Mesh4D> splines) { String pcaFile = heartBase + "\\CardiacModel\\phase_" + phase + ".ccm"; ActiveShapeModel asm = new ActiveShapeModel(pcaFile); Mesh allComp = asm.getModel(parameters); if (phase == 0) { for (int i = 0; i < info.numAnatComp; i++) { splines.add(new Mesh4D()); } } int count = 0; for (heartComponents hc : heartComponents.values()) { Mesh comp = new Mesh(); SimpleMatrix pts = allComp .getPoints() .getSubMatrix(info.vertexOffs[count], 0, hc.getNumVertices(), info.vertexDim); // rotate and translate points for (int i = 0; i < pts.getRows(); i++) { SimpleVector row = SimpleOperators.multiply(rot, pts.getRow(i)); row.add(trans); pts.setRowValue(i, row); } comp.setPoints(pts); comp.setConnectivity( allComp .getConnectivity() .getSubMatrix(info.triangleOffs[count], 0, hc.getNumTriangles(), 3)); splines.get(count).addMesh(comp); count++; } }
public void setData(int x, int y, int z, DarkFieldPCA myPCA) { SimpleMatrix eigenVectors = myPCA.getEigenVectors(); SimpleVector eigenValues = myPCA.getEigenValues(); for (int i = 0; i < fieldList.size(); i++) { SimpleVector eigenVec = eigenVectors.getCol(i); double eigenVal = eigenValues.getElement(i); eigenVec = eigenVec.multipliedBy(eigenVal); fieldList.get(i).setVector(x, y, z, eigenVec); } // /** // * Threshold that checks, if 3 component of eigenvalues is too small // * If 3 component is too small, don't consider it as a fiber orientation // * and ignore it // */ // double th = 1E-10; // SimpleVector fiberDir; // if(myPCA.getEigenValues().getElement(2)<th){ // fiberDir = new SimpleVector(3); // }else{ // fiberDir = myPCA.getEigenVectors().getCol(2).normalizedL2(); // fiberDir.multiplyBy(myPCA.getEigenValues().getElement(2)); // } }
public static void printSimpleMatrix(SimpleMatrix A) { int n = A.getRows(); int m = A.getCols(); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { System.out.print(A.getElement(i, j) + "\t"); } System.out.print("\n"); } }
/** * 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)); }
/** * method to calculate a mapping K from two source positions C0, C1 to a plane C0 (C1) is the * source position from the first (second) view */ public void createMappingToEpipolarPlane() { // set up source matrices // SimpleVector C0 = this.view1.C; SimpleVector C1 = this.view2.C; // compute Pluecker coordinates // double L01 = C0.getElement(0) * C1.getElement(1) - C0.getElement(1) * C1.getElement(0); double L02 = C0.getElement(0) * C1.getElement(2) - C0.getElement(2) * C1.getElement(0); double L03 = C0.getElement(0) * C1.getElement(3) - C0.getElement(3) * C1.getElement(0); double L12 = C0.getElement(1) * C1.getElement(2) - C0.getElement(2) * C1.getElement(1); double L13 = C0.getElement(1) * C1.getElement(3) - C0.getElement(3) * C1.getElement(1); double L23 = C0.getElement(2) * C1.getElement(3) - C0.getElement(3) * C1.getElement(2); // construct B (6x1) // SimpleVector B = new SimpleVector(L01, L02, L03, L12, L13, L23); // compute infinity point in direction of B // SimpleVector N = new SimpleVector(-L03, -L13, -L23, 0); // compute plane E0 containing B and X0=(0,0,0,1) // SimpleVector E0 = SimpleOperators.getPlueckerJoin(B, new SimpleVector(0, 0, 0, 1)); // find othonormal basis from plane normals // // (vectors are of 3x1) SimpleVector a2 = new SimpleVector(E0.getElement(0), E0.getElement(1), E0.getElement(2)); SimpleVector a3 = new SimpleVector(N.getElement(0), N.getElement(1), N.getElement(2)); // set vectors to unit length a2.normalizeL2(); a3.normalizeL2(); // calculate cross product to get the last basis vector // SimpleVector a1 = General.crossProduct(a2, a3).negated(); // (a1 is already of unit length -> no normalization needed) // set up assembly matrix A (4x3) // SimpleMatrix A = new SimpleMatrix(4, 3); A.setSubColValue(0, 0, a1); A.setSubColValue(0, 1, a2); A.setSubColValue(0, 2, C0); // store mapping matrix K (4x3 = 4x4 * 4x3) // this.K = SimpleOperators.multiplyMatrixProd(SimpleOperators.getPlueckerMatrixDual(B), A); }
private void CreatePhantom() { // Iterate over all pixels and sum up intensity values of all corresponding ellipses double sizeX = (double) super.getSize()[0]; double sizeY = (double) super.getSize()[1]; for (int i = 0; i < super.getSize()[0]; ++i) { double x = ((double) i - (sizeX - 1) / 2.0) / ((sizeX - 1) / 2.0); for (int j = 0; j < super.getSize()[1]; ++j) { double y = ((double) j - (sizeY - 1) / 2.0) / ((sizeY - 1) / 2.0); super.setAtIndex(i, super.getSize()[1] - j - 1, 0.f); for (int k = 0; k < Ellipses.getRows(); ++k) { // Extract the ellipse properties here double xc = x - Ellipses.getElement(k, 3); double yc = y - Ellipses.getElement(k, 4); double phi = Ellipses.getElement(k, 5) * Math.PI / 180.0; double cos = Math.cos(phi); double sin = Math.sin(phi); double asq = Ellipses.getElement(k, 1) * Ellipses.getElement(k, 1); double bsq = Ellipses.getElement(k, 2) * Ellipses.getElement(k, 2); double Val = Ellipses.getElement(k, 0); // Check if this pixel is part of the ellipse, if yes, add the given intensity value to it double help = Math.pow((xc * cos + yc * sin), 2.0); double help2 = Math.pow((yc * cos - xc * sin), 2.0); if (help / asq + help2 / bsq <= 1.0) super.setAtIndex( i, super.getSize()[1] - j - 1, super.getAtIndex(i, super.getSize()[1] - j - 1) + (float) Val); } } } }
private SimpleMatrix ShepMod() { // Modified (better contrast) Shepp-Logan Phantom according // to P. A. Toft, "The Radon Transform, Theory and Implementation" // (unpublished dissertation), p. 199. // One row describes properties for a single ellipse // Colum Values: A a b x0 y0 phi SimpleMatrix Shep = new SimpleMatrix(10, 6); Shep.setRowValue(0, new SimpleVector(new double[] {1.0, 0.69, 0.92, 0, 0, 0})); Shep.setRowValue(1, new SimpleVector(new double[] {-0.8, 0.6624, 0.8740, 0, -0.0184, 0})); Shep.setRowValue(2, new SimpleVector(new double[] {-0.2, 0.1100, 0.3100, 0.22, 0.0, -18.0})); Shep.setRowValue(3, new SimpleVector(new double[] {-0.2, 0.1600, 0.4100, -0.22, 0.0, 18.0})); Shep.setRowValue(4, new SimpleVector(new double[] {0.1, 0.2100, 0.2500, 0, 0.35, 0})); Shep.setRowValue(5, new SimpleVector(new double[] {0.1, 0.0460, 0.0460, 0, 0.1, 0})); Shep.setRowValue(6, new SimpleVector(new double[] {0.1, 0.0460, 0.0460, 0, -0.1, 0})); Shep.setRowValue(7, new SimpleVector(new double[] {0.1, 0.0460, 0.0230, -0.08, -0.605, 0})); Shep.setRowValue(8, new SimpleVector(new double[] {0.1, 0.0230, 0.0230, 0, -0.606, 0})); Shep.setRowValue(9, new SimpleVector(new double[] {0.1, 0.0230, 0.0460, 0.06, -0.605, 0})); return Shep; }
private synchronized void initProjectionMatrix(int projectionNumber) { // load projection Matrix for current Projection. SimpleMatrix pMat = getGeometry().getProjectionMatrix(projectionNumber).computeP(); float[] pMatFloat = new float[pMat.getCols() * pMat.getRows()]; for (int j = 0; j < pMat.getRows(); j++) { for (int i = 0; i < pMat.getCols(); i++) { pMatFloat[(j * pMat.getCols()) + i] = (float) pMat.getElement(j, i); } } JCudaDriver.cuMemcpyHtoD( projectionMatrix, Pointer.to(pMatFloat), Sizeof.FLOAT * pMatFloat.length); }
private SimpleMatrix ShepOrig() { // Original Shepp-Logan Phantom according to: // Shepp, L. A., & Logan, B. F. (1974). // The Fourier reconstruction of a head section-LA Shepp. // IEEE Transactions on Nuclear Science, NS-21, 21�43. // One row describes properties for a single ellipse // Colum Values: A a b x0 y0 phi SimpleMatrix Shep = new SimpleMatrix(10, 6); Shep.setRowValue(0, new SimpleVector(new double[] {2.0, 0.69, 0.92, 0, 0, 0})); Shep.setRowValue(1, new SimpleVector(new double[] {-0.98, 0.6624, 0.8740, 0, -0.0184, 0})); Shep.setRowValue(2, new SimpleVector(new double[] {-0.02, 0.1100, 0.3100, 0.22, 0.0, -18.0})); Shep.setRowValue(3, new SimpleVector(new double[] {-0.02, 0.1600, 0.4100, -0.22, 0.0, 18.0})); Shep.setRowValue(4, new SimpleVector(new double[] {0.01, 0.2100, 0.2500, 0, 0.35, 0})); Shep.setRowValue(5, new SimpleVector(new double[] {0.01, 0.0460, 0.0460, 0, 0.1, 0})); Shep.setRowValue(6, new SimpleVector(new double[] {0.01, 0.0460, 0.0460, 0, -0.1, 0})); Shep.setRowValue(7, new SimpleVector(new double[] {0.01, 0.0460, 0.0230, -0.08, -0.605, 0})); Shep.setRowValue(8, new SimpleVector(new double[] {0.01, 0.0230, 0.0230, 0, -0.606, 0})); Shep.setRowValue(9, new SimpleVector(new double[] {0.01, 0.0230, 0.0460, 0.06, -0.605, 0})); return Shep; }
private synchronized void initProjectionMatrix(int projectionNumber) { // load projection Matrix for current Projection. SimpleMatrix pMat = getGeometry().getProjectionMatrix(projectionNumber).computeP(); float[] pMatFloat = new float[pMat.getCols() * pMat.getRows()]; for (int j = 0; j < pMat.getRows(); j++) { for (int i = 0; i < pMat.getCols(); i++) { pMatFloat[(j * pMat.getCols()) + i] = (float) pMat.getElement(j, i); } } // Obtain the global pointer to the view matrix from // the module if (projectionMatrix == null) projectionMatrix = context.createFloatBuffer(pMatFloat.length, Mem.READ_ONLY); projectionMatrix.getBuffer().put(pMatFloat); projectionMatrix.getBuffer().rewind(); commandQueue.putWriteBuffer(projectionMatrix, true).finish(); }
/** * Constructs the triangle corresponding to the i-th face in a mesh given the connectivity * information fcs and the vertices vtc and adds it to the CompoundShape. * * @param vtc The vertices of the mesh. * @param fcs The faces of the mesh, i.e connectivity information. * @param i The index of the face to be constructed. */ private void addTriangleAtIndex(CompoundShape cs, SimpleMatrix vtc, SimpleMatrix fcs, int i) { SimpleVector face = fcs.getRow(i); SimpleVector dirU = vtc.getRow((int) face.getElement(1)); dirU.subtract(vtc.getRow((int) face.getElement(0))); double l2 = dirU.normL2(); SimpleVector dirV = vtc.getRow((int) face.getElement(2)); dirV.subtract(vtc.getRow((int) face.getElement(0))); if (dirV.normL2() < l2) { l2 = dirV.normL2(); } double nN = General.crossProduct(dirU.normalizedL2(), dirV.normalizedL2()).normL2(); if (l2 < Math.sqrt(CONRAD.DOUBLE_EPSILON) || nN < Math.sqrt(CONRAD.DOUBLE_EPSILON)) { } else { Triangle t = new Triangle( new PointND(vtc.getRow((int) face.getElement(0))), new PointND(vtc.getRow((int) face.getElement(1))), new PointND(vtc.getRow((int) face.getElement(2)))); cs.add(t); } }
@Override public Grid2D applyToolToImage(Grid2D imageProcessor) { FloatProcessor imp = new FloatProcessor(imageProcessor.getWidth(), imageProcessor.getHeight()); imp.setPixels(imageProcessor.getBuffer()); if (!initBead) initializeBead(); ImageProcessor imp1 = imp.duplicate(); // original double[][] beadMean3D = config.getBeadMeanPosition3D(); // [beadNo][x,y,z] double[] uv = new double[1]; SimpleMatrix pMatrix = config.getGeometry().getProjectionMatrix(imageIndex).computeP(); // [projection #][bead #][u, v, state[0: initial, 1: registered, 2: updated by hough searching]] double[][][] beadPosition2D = config.getBeadPosition2D(); int noBeadRegistered = 0; double[][] xy1 = new double[WeightBearingBeadPositionBuilder.beadNo][2]; // original double[][] xy2 = new double[WeightBearingBeadPositionBuilder.beadNo] [2]; // warped (mapped to the mean), control points, reference double[][] xy1_hat = new double[WeightBearingBeadPositionBuilder.beadNo][2]; // original double[][] xy2_hat = new double[WeightBearingBeadPositionBuilder.beadNo][2]; // original // double distanceReferenceToCurrentBead = 0; for (int i = WeightBearingBeadPositionBuilder.currentBeadNo; i >= 0; i--) { if (beadMean3D[i][0] != 0 || beadMean3D[i][1] != 0 || beadMean3D[i][2] != 0) { // assume bead 3d is registered. uv = compute2DCoordinates(beadMean3D[i], pMatrix); // find bead location if registered by txt: state 1 if (beadPosition2D[imageIndex][i][2] == 1) { noBeadRegistered++; if (isDisplay) { imp1.setValue(2); imp1.drawLine( (int) Math.round(beadPosition2D[imageIndex][i][0] - 10), (int) Math.round(beadPosition2D[imageIndex][i][1] - 10), (int) Math.round(beadPosition2D[imageIndex][i][0] + 10), (int) Math.round(beadPosition2D[imageIndex][i][1] + 10)); imp1.drawLine( (int) Math.round(beadPosition2D[imageIndex][i][0] - 10), (int) Math.round(beadPosition2D[imageIndex][i][1] + 10), (int) Math.round(beadPosition2D[imageIndex][i][0] + 10), (int) Math.round(beadPosition2D[imageIndex][i][1] - 10)); imp1.drawString( "Bead " + i + " (state:" + (int) beadPosition2D[imageIndex][i][2] + ")", (int) beadPosition2D[imageIndex][i][0], (int) beadPosition2D[imageIndex][i][1] - 10); } xy1[noBeadRegistered - 1][0] = beadPosition2D[imageIndex][i][0]; xy1[noBeadRegistered - 1][1] = beadPosition2D[imageIndex][i][1]; xy2[noBeadRegistered - 1][0] = uv[0]; xy2[noBeadRegistered - 1][1] = uv[1]; } else if (imageIndex != 0 && imageIndex != config.getGeometry().getNumProjectionMatrices() - 1) { if (beadPosition2D[imageIndex - 1][i][2] == 1 && beadPosition2D[imageIndex + 1][i][2] == 1) { noBeadRegistered++; double xMean = (beadPosition2D[imageIndex - 1][i][0] + beadPosition2D[imageIndex - 1][i][0]) / 2; double yMean = (beadPosition2D[imageIndex + 1][i][1] + beadPosition2D[imageIndex + 1][i][1]) / 2; if (isDisplay) { imp1.setValue(2); imp1.drawLine( (int) Math.round(xMean - 10), (int) Math.round(yMean - 10), (int) Math.round(xMean + 10), (int) Math.round(yMean + 10)); imp1.drawLine( (int) Math.round(xMean - 10), (int) Math.round(yMean + 10), (int) Math.round(xMean + 10), (int) Math.round(yMean - 10)); imp1.drawString("Bead " + i + " (state:" + "M)", (int) xMean, (int) yMean - 10); } xy1[noBeadRegistered - 1][0] = xMean; xy1[noBeadRegistered - 1][1] = yMean; xy2[noBeadRegistered - 1][0] = uv[0]; xy2[noBeadRegistered - 1][1] = uv[1]; } } // mean projected bead // imp1.drawLine((int) Math.round(uv[0]-10), (int) Math.round(uv[1]), (int) // Math.round(uv[0]+10), (int) Math.round(uv[1])); // imp1.drawLine((int) Math.round(uv[0]), (int) Math.round(uv[1]-10), (int) // Math.round(uv[0]), (int) Math.round(uv[1]+10)); } } if (isDisplay) { for (int x = 0; x < config.getGeometry().getDetectorWidth(); x += 50) imp1.drawLine(x, 0, x, config.getGeometry().getDetectorHeight()); for (int y = 0; y < config.getGeometry().getDetectorHeight(); y += 50) imp1.drawLine(0, y, config.getGeometry().getDetectorWidth(), y); } if (isCornerIncluded) { xy1[noBeadRegistered + 0][0] = 0; xy1[noBeadRegistered + 0][1] = 0; xy2[noBeadRegistered + 0][0] = 0; xy2[noBeadRegistered + 0][1] = 0; xy1[noBeadRegistered + 1][0] = 0; xy1[noBeadRegistered + 1][1] = config.getGeometry().getDetectorHeight(); xy2[noBeadRegistered + 1][0] = 0; xy2[noBeadRegistered + 1][1] = config.getGeometry().getDetectorHeight(); xy1[noBeadRegistered + 2][0] = config.getGeometry().getDetectorWidth(); xy1[noBeadRegistered + 2][1] = 0; xy2[noBeadRegistered + 2][0] = config.getGeometry().getDetectorWidth(); xy2[noBeadRegistered + 2][1] = 0; xy1[noBeadRegistered + 3][0] = config.getGeometry().getDetectorWidth(); xy1[noBeadRegistered + 3][1] = config.getGeometry().getDetectorHeight(); xy2[noBeadRegistered + 3][0] = config.getGeometry().getDetectorWidth(); xy2[noBeadRegistered + 3][1] = config.getGeometry().getDetectorHeight(); noBeadRegistered = noBeadRegistered + 4; } boolean fScaling = true; double minX = Double.MAX_VALUE; double maxX = 0; double minY = Double.MAX_VALUE; double maxY = 0; double c = 0; if (fScaling) { // ----- scaling to reduce condition # of A matrix for (int i = 0; i < noBeadRegistered; i++) { minX = Math.min(minX, xy1[i][0]); maxX = Math.max(maxX, xy1[i][0]); minY = Math.min(minY, xy1[i][1]); maxY = Math.max(maxY, xy1[i][1]); } c = Math.max(maxX - minX, maxY - minY); for (int i = 0; i < noBeadRegistered; i++) { xy1_hat[i][0] = (xy1[i][0] - minX) / c; xy1_hat[i][1] = (xy1[i][1] - minY) / c; xy2_hat[i][0] = (xy2[i][0] - minX) / c; xy2_hat[i][1] = (xy2[i][1] - minY) / c; } } else { xy1_hat = xy1; xy2_hat = xy2; } ImageProcessor imp2 = imp1.duplicate(); // warped /* * A*x = b * Matrix A = (n + 3) * (n + 3); * n (noBeadRegistered + 4): # of control points + 4 corner points (assume corner points are static) */ int n = noBeadRegistered + 3; SimpleMatrix A = new SimpleMatrix(n, n); SimpleVector x_x = new SimpleVector(n); SimpleVector x_y = new SimpleVector(n); SimpleVector b_x = new SimpleVector(n); SimpleVector b_y = new SimpleVector(n); double rij = 0; double valA = 0; double valb_x = 0; double valb_y = 0; // Matrix L formation // alpha: mean of distances between control points' xy-projections) is a constant only present // on the diagonal of K // lambda: TPS smoothing regularization coefficient double alpha = 0.0; double lambda = 1.6; // 1.6 for (int i = 0; i < noBeadRegistered; i++) { // i= # of row for (int j = i; j < noBeadRegistered; j++) { // j= # of column alpha += Math.sqrt( Math.pow(xy2_hat[i][0] - xy2_hat[j][0], 2) + Math.pow(xy2_hat[i][1] - xy2_hat[j][1], 2)); } } alpha = alpha / Math.pow(noBeadRegistered, 2); for (int i = 0; i < n; i++) { // i= # of row for (int j = i; j < n; j++) { // j= # of column if (i < 3 && j < 3) valA = 0; else if (i >= 3 && j >= 3 && i == j) { valA = Math.pow(alpha, 2) * lambda; // valA = lambda; if (imageIndex < 10) System.out.println("Regularization = " + valA + ", lambda= " + lambda); } else if (i == 0 && j >= 0) valA = 1; else if (i == 1 && j >= 3) valA = xy1_hat[j - 3][0]; else if (i == 2 && j >= 3) valA = xy1_hat[j - 3][1]; else { rij = Math.pow(xy1_hat[j - 3][0] - xy1_hat[i - 3][0], 2) + Math.pow(xy1_hat[j - 3][1] - xy1_hat[i - 3][1], 2); if (rij == 0) valA = 0; else valA = rij * Math.log(rij); } A.setElementValue(i, j, valA); A.setElementValue(j, i, valA); } if (i < 3) { valb_x = 0; valb_y = 0; } else { // valb_x = xy2_hat[i-3][0]-xy1_hat[i-3][0]; // valb_y = xy2_hat[i-3][1]-xy1_hat[i-3][1]; valb_x = xy2[i - 3][0] - xy1[i - 3][0]; valb_y = xy2[i - 3][1] - xy1[i - 3][1]; // if (imageIndex > 150 && imageIndex < 170) // System.out.println("Idx" + imageIndex + ",Elevation" + (i-3) + ": " + valb_x + "---" // + valb_y); } b_x.setElementValue(i, valb_x); b_y.setElementValue(i, valb_y); } // System.out.println("A condition number=" + A.conditionNumber(MatrixNormType.MAT_NORM_L1)); // System.out.println("A condition number=" + A.conditionNumber(MatrixNormType.MAT_NORM_LINF)); x_x = Solvers.solveLinearSysytemOfEquations(A, b_x); x_y = Solvers.solveLinearSysytemOfEquations(A, b_y); if (fScaling) { // ----- pixel space coefficients a, b scaling back double tmpA0 = x_x.getElement(0) - x_x.getElement(1) * (minX / c) - x_x.getElement(2) * (minY / c); for (int j = 0; j < noBeadRegistered; j++) { tmpA0 -= Math.log(c) * 2 * x_x.getElement(j + 3) * (Math.pow(xy1_hat[j][0], 2) + Math.pow(xy1_hat[j][1], 2)); } x_x.setElementValue(0, tmpA0); tmpA0 = x_y.getElement(0) - x_y.getElement(1) * (minX / c) - x_y.getElement(2) * (minY / c); for (int j = 0; j < noBeadRegistered; j++) { tmpA0 -= Math.log(c) * 2 * x_y.getElement(j + 3) * (Math.pow(xy1_hat[j][0], 2) + Math.pow(xy1_hat[j][1], 2)); } x_y.setElementValue(0, tmpA0); x_x.setElementValue(1, x_x.getElement(1) / c); x_y.setElementValue(1, x_y.getElement(1) / c); x_x.setElementValue(2, x_x.getElement(2) / c); x_y.setElementValue(2, x_y.getElement(2) / c); for (int i = 3; i < n; i++) { x_x.setElementValue(i, x_x.getElement(i) / Math.pow(c, 2)); x_y.setElementValue(i, x_y.getElement(i) / Math.pow(c, 2)); } // ----- pixel space coefficients a, b scaling back end } double devU = 0; double devV = 0; // Do warping // if (imageIndex == 0) { for (int y = 0; y < config.getGeometry().getDetectorHeight(); y++) { // for (int y=252; y<253; y++) { for (int x = 0; x < config.getGeometry().getDetectorWidth(); x++) { // for (int x=606; x<607; x++) { devU = x_x.getElement(0) + x_x.getElement(1) * x + x_x.getElement(2) * y; devV = x_y.getElement(0) + x_y.getElement(1) * x + x_y.getElement(2) * y; for (int i = 0; i < noBeadRegistered; i++) { rij = Math.pow(xy1[i][0] - x, 2) + Math.pow(xy1[i][1] - y, 2); if (rij > 0) { devU += x_x.getElement(i + 3) * rij * Math.log(rij); devV += x_y.getElement(i + 3) * rij * Math.log(rij); } } // devU = 0; // devV = 0; imp2.setf(x, y, (float) imp1.getInterpolatedValue(x - devU, y - devV)); // System.out.println("x, y=" + x + ", " + y + "\t" + devU + ", " + devV); // maxDevU = Math.max(maxDevU, devU); // maxDevV = Math.max(maxDevV, devV); } } // Error estimate after transformation // for (int i=0; i<= WeightBearingBeadPositionBuilder.currentBeadNo; i++){ // // if (beadMean3D[i][0] != 0 || beadMean3D[i][1] != 0 || beadMean3D[i][2] != 0){ // assume // bead 3d is registered. // // // find bead location if registered by txt: state 1 // if (beadPosition2D[imageIndex][i][2] == 1){ // // // Projected Reference // uv = compute2DCoordinates(beadMean3D[i], pMatrix); // double x = uv[0]; // double y = uv[1]; // // bead detected position in 2d // // Transform to 2D coordinates, time variant position // //beadPosition2D[imageIndex][i][0]; // //beadPosition2D[imageIndex][i][1]; // // devU = x_x.getElement(0) + x_x.getElement(1)*x + x_x.getElement(2)*y; // devV = x_y.getElement(0) + x_y.getElement(1)*x + x_y.getElement(2)*y; // for (int j=0; j<noBeadRegistered; j++){ // rij = Math.pow(xy1[j][0]-x, 2) + Math.pow(xy1[j][1]-y, 2); // if (rij > 0) { // devU += x_x.getElement(j+3)*rij*Math.log(rij); // devV += x_y.getElement(j+3)*rij*Math.log(rij); // } // } // // distanceReferenceToCurrentBead += // Math.sqrt(Math.pow(uv[0]-(beadPosition2D[imageIndex][i][0]+devU), // 2)+Math.pow(uv[1]-(beadPosition2D[imageIndex][i][1]+devV), 2)); // // } // } // } // System.out.println("Euclidean distance\t" + imageIndex + "\t" + // distanceReferenceToCurrentBead/noBeadRegistered); // } if (isDisplay) { for (int i = WeightBearingBeadPositionBuilder.currentBeadNo; i >= 0; i--) { if (beadMean3D[i][0] != 0 || beadMean3D[i][1] != 0 || beadMean3D[i][2] != 0) { // assume bead 3d is registered. uv = compute2DCoordinates(beadMean3D[i], pMatrix); imp2.setValue(2); // mean projected bead imp2.drawLine( (int) Math.round(uv[0] - 10), (int) Math.round(uv[1]), (int) Math.round(uv[0] + 10), (int) Math.round(uv[1])); imp2.drawLine( (int) Math.round(uv[0]), (int) Math.round(uv[1] - 10), (int) Math.round(uv[0]), (int) Math.round(uv[1] + 10)); } } } Grid2D result = new Grid2D((float[]) imp2.getPixels(), imp2.getWidth(), imp2.getHeight()); 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); }