public void process(String dir, double lambda, double tolerance, double a) throws IOException { File dataf = new File(dir); File outdir = new File(dir, "filtered"); outdir.mkdir(); String objfile = new File(dataf, "Sphere.obj").getAbsolutePath(); SphericalMaxProjection smp = new SphericalMaxProjection(objfile); Point3f[] vertices = smp.getSphere().getVertices(); int[] faces = smp.getSphere().getFaces(); int[][] neighbors = calculateNeighbors(faces, vertices.length); File[] files = dataf.listFiles(); for (int i = 0; i < files.length; i++) { if (!files[i].getName().endsWith(".vertices")) continue; short[] original = smp.loadMaxima(files[i].getAbsolutePath()); double diff = 0; float[] current = new float[original.length]; for (int c = 0; c < current.length; c++) current[c] = original[c]; int iter = 0; do { float[] next = new float[vertices.length]; diff = step(neighbors, current, next, original, lambda, a); current = next; iter++; } while (diff > tolerance); for (int c = 0; c < current.length; c++) original[c] = (short) Math.round(current[c]); System.out.println(iter + " iterations"); smp.saveMaxima(new File(outdir, files[i].getName()).getAbsolutePath(), original); } }
public int[] setSphereColors(SphericalMaxProjection smp, ColorProcessor ip) { Point2f polar = new Point2f(); Point2D.Double out = new Point2D.Double(); int[] colors = new int[smp.getSphere().nVertices]; int idx = 0; for (Point3f v : smp.getSphere().getVertices()) { smp.getPolar(v, polar); projection.transformRadians(polar.x, polar.y, out); int x = (int) out.x - minx; int y = maxy - (int) out.y; colors[idx++] = ip.get(x, y); } return colors; }
public void indicateCameraContributions(int[][][] colors) throws IOException { File out = new File(outputdir, "contributions.vertices"); if (out.exists()) return; Point3f[] vertices = smp.getSphere().getVertices(); int[] res = new int[vertices.length]; for (int v = 0; v < vertices.length; v++) { Point3f vertex = vertices[v]; double r = 0, g = 0, b = 0; double sum = 0; for (int a = 0; a < nAngles; a++) { Point3f xvtx = new Point3f(vertex); if (transforms[a] != null) transforms[a].transform(xvtx); float w1 = weights[CAMERA1][LEFT][a].getWeight(xvtx.x, xvtx.y, xvtx.z); float w2 = weights[CAMERA1][RIGHT][a].getWeight(xvtx.x, xvtx.y, xvtx.z); float w3 = weights[CAMERA2][LEFT][a].getWeight(xvtx.x, xvtx.y, xvtx.z); float w4 = weights[CAMERA2][RIGHT][a].getWeight(xvtx.x, xvtx.y, xvtx.z); int c1 = colors[CAMERA1][LEFT][a]; int c2 = colors[CAMERA1][RIGHT][a]; int c3 = colors[CAMERA2][LEFT][a]; int c4 = colors[CAMERA2][RIGHT][a]; int r1 = (c1 & 0xff0000) >> 16, g1 = (c1 & 0xff00) >> 8, b1 = (c1 & 0xff); int r2 = (c2 & 0xff0000) >> 16, g2 = (c2 & 0xff00) >> 8, b2 = (c2 & 0xff); int r3 = (c3 & 0xff0000) >> 16, g3 = (c3 & 0xff00) >> 8, b3 = (c3 & 0xff); int r4 = (c4 & 0xff0000) >> 16, g4 = (c4 & 0xff00) >> 8, b4 = (c4 & 0xff); double rc = w1 * r1 + w2 * r2 + w3 * r3 + w4 * r4; double gc = w1 * g1 + w2 * g2 + w3 * g3 + w4 * g4; double bc = w1 * b1 + w2 * b2 + w3 * b3 + w4 * b4; r += rc; g += gc; b += bc; sum += w1 + w2 + w3 + w4; } r /= sum; g /= sum; b /= sum; int ir = r > 255 ? 255 : (int) r; int ig = g > 255 ? 255 : (int) g; int ib = b > 255 ? 255 : (int) b; res[v] = (ir << 16) + (ig << 8) + ib; } SphericalMaxProjection.saveIntData(res, out.getAbsolutePath()); }
public void testCameraFusion() throws IOException { File dir = new File(outputdir, "test"); dir.mkdir(); Point3f[] vertices = smp.getSphere().getVertices(); for (int ill = 0; ill < 2; ill++) { for (int cam = 0; cam < 2; cam++) { for (int a = 0; a < nAngles; a++) { File outf = new File(dir, getFile(0, a, angleInc, cam, ill, 0)); if (outf.exists()) continue; short[] res = new short[vertices.length]; for (int v = 0; v < vertices.length; v++) { Point3f vertex = new Point3f(vertices[v]); if (transforms[a] != null) transforms[a].transform(vertex); res[v] = (short) (100 * weights[cam][ill][a].getWeight(vertex.x, vertex.y, vertex.z)); } SphericalMaxProjection.saveShortData(res, outf.getAbsolutePath()); } } } }
public void prepareForProjection(SphericalMaxProjection smp, int width) { double globeRadius = findRadiusForWidth(width, 0, 1000f); projection.setEllipsoid(new Ellipsoid("", globeRadius, globeRadius, 0.0D, "")); projection.initialize(); if (!projection.hasInverse()) throw new RuntimeException("Inverse mapping missing"); minx = Integer.MAX_VALUE; maxx = -minx; miny = minx; maxy = -minx; double dlon = projection.getMaxLongitude() - projection.getMinLongitude(); double dlat = projection.getMaxLatitude() - projection.getMinLatitude(); Point2D.Double tmpin = new Point2D.Double(); Point2D.Double tmpout = new Point2D.Double(); for (int lo = 0; lo <= 100; lo++) { for (int la = 0; la <= 100; la++) { tmpin.x = (lo - 50) * dlon / 100; tmpin.y = (la - 50) * dlat / 100; tmpin.x = (lo - 50) * dlon / 100; tmpin.y = (la - 50) * dlat / 100; projection.transformRadians(tmpin, tmpout); if (tmpout.x < minx) minx = (int) tmpout.x; if (tmpout.y < miny) miny = (int) tmpout.y; if (tmpout.x > maxx) maxx = (int) tmpout.x; if (tmpout.y > maxy) maxy = (int) tmpout.y; } } this.w = maxx - minx + 1; this.h = maxy - miny + 1; vIndices = new int[w * h][3]; vertexWeights = new float[w * h][3]; Point3f p = new Point3f(); Point3f[] vertices = smp.getSphere().getVertices(); int index = 0; for (int y = maxy; y >= miny; y--) { for (int x = minx; x <= maxx; x++) { Point2D.Double in = new Point2D.Double(x, y); Point2D.Double out = new Point2D.Double(); out = projection.inverseTransformRadians(in, out); double lon = out.x; double lat = out.y; if (lat >= projection.getMaxLatitude() || lat <= projection.getMinLatitude() || lon >= projection.getMaxLongitude() || lon <= projection.getMinLongitude()) { index++; continue; } double sLon = (float) Math.sin(lon); double cLon = (float) Math.cos(lon); double sLat = (float) Math.sin(lat); double cLat = (float) Math.cos(lat); smp.getPoint(sLon, cLon, sLat, cLat, p); smp.getThreeNearestVertexIndices(p, vIndices[index]); // interpolate according to distance float d0 = 1 / p.distance(vertices[vIndices[index][0]]); float d1 = 1 / p.distance(vertices[vIndices[index][1]]); float d2 = 1 / p.distance(vertices[vIndices[index][2]]); float sum = d0 + d1 + d2; vertexWeights[index][0] = d0 / sum; vertexWeights[index][1] = d1 / sum; vertexWeights[index][2] = d2 / sum; index++; } } }
public void fuse(int tp) throws IOException { boolean done = true; for (int l = 0; l < nLayers; l++) { if (!new File(outputdir, String.format("tp%04d_%02d.vertices", tp, l)).exists()) { done = false; break; } } if (done) return; int nVertices = smp.getSphere().nVertices; short[][][][][] m = new short[2][2][nAngles][nLayers][]; for (int a = 0; a < nAngles; a++) { for (int l = 0; l < nLayers; l++) { m[CAMERA1][LEFT][a][l] = SphericalMaxProjection.loadShortData( inputdir .getFile(CAMERA1, getFile(tp, a, angleInc, CAMERA1, LEFT, l)) .getAbsolutePath(), nVertices); m[CAMERA1][RIGHT][a][l] = SphericalMaxProjection.loadShortData( inputdir .getFile(CAMERA1, getFile(tp, a, angleInc, CAMERA1, RIGHT, l)) .getAbsolutePath(), nVertices); m[CAMERA2][LEFT][a][l] = SphericalMaxProjection.loadShortData( inputdir .getFile(CAMERA2, getFile(tp, a, angleInc, CAMERA2, LEFT, l)) .getAbsolutePath(), nVertices); m[CAMERA2][RIGHT][a][l] = SphericalMaxProjection.loadShortData( inputdir .getFile(CAMERA2, getFile(tp, a, angleInc, CAMERA2, RIGHT, l)) .getAbsolutePath(), nVertices); } } if (adjustModes) { float refmode = SphericalMaxProjection.getMode(m[CAMERA1][LEFT][0][0]); for (int a = 0; a < nAngles; a++) { short[] data = m[CAMERA1][LEFT][a][0]; float mode = SphericalMaxProjection.getMode(data); SphericalMaxProjection.add(data, (short) (refmode - mode)); data = m[CAMERA1][RIGHT][a][0]; mode = SphericalMaxProjection.getMode(data); SphericalMaxProjection.add(data, (short) (refmode - mode)); data = m[CAMERA2][LEFT][a][0]; mode = SphericalMaxProjection.getMode(data); SphericalMaxProjection.add(data, (short) (refmode - mode)); data = m[CAMERA2][RIGHT][a][0]; mode = SphericalMaxProjection.getMode(data); SphericalMaxProjection.add(data, (short) (refmode - mode)); } } for (int l = 0; l < nLayers; l++) { File out = new File(outputdir, String.format("tp%04d_%02d.vertices", tp, l)); Point3f[] vertices = smp.getSphere().getVertices(); float[] res = new float[vertices.length]; for (int v = 0; v < vertices.length; v++) { Point3f vertex = vertices[v]; float sum = 0; res[v] = 0; for (int a = 0; a < nAngles; a++) { Point3f xvtx = new Point3f(vertex); if (transforms[a] != null) transforms[a].transform(xvtx); float w1 = weights[CAMERA1][LEFT][a].getWeight(xvtx.x, xvtx.y, xvtx.z); float w2 = weights[CAMERA1][RIGHT][a].getWeight(xvtx.x, xvtx.y, xvtx.z); float w3 = weights[CAMERA2][LEFT][a].getWeight(xvtx.x, xvtx.y, xvtx.z); float w4 = weights[CAMERA2][RIGHT][a].getWeight(xvtx.x, xvtx.y, xvtx.z); float m1 = (m[CAMERA1][LEFT][a][l][v] & 0xffff); float m2 = (m[CAMERA1][RIGHT][a][l][v] & 0xffff); float m3 = (m[CAMERA2][LEFT][a][l][v] & 0xffff); float m4 = (m[CAMERA2][RIGHT][a][l][v] & 0xffff); sum += w1 + w2 + w3 + w4; res[v] += (w1 * m1 + w2 * m2 + w3 * m3 + w4 * m4); } res[v] = sum == 0 ? 0 : res[v] / sum; } short[] sData = new short[res.length]; for (int v = 0; v < res.length; v++) sData[v] = (short) res[v]; if (saveOutput) SphericalMaxProjection.saveShortData(sData, out.getAbsolutePath()); } }