Exemplo n.º 1
0
  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 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 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;
  }
  /**
   * Prepare fusion, using a single input folder.
   *
   * @param indir
   * @param nAngles
   * @param angleInc
   * @param transformations
   * @param saveOutput
   * @throws IOException
   */
  public void prepareFusion(
      String indir,
      int nAngles,
      int angleInc,
      int nLayers,
      Matrix4f[] transformations,
      boolean saveOutput)
      throws IOException {
    if (!indir.endsWith(File.separator)) indir += File.separator;
    this.inputdir = new SingleInputFolder(new File(indir));
    this.saveOutput = saveOutput;
    this.smp = new SphericalMaxProjection(indir + "Sphere.obj");
    this.outputdir = new File(indir, "fused");
    this.angleInc = angleInc;
    this.nAngles = nAngles;
    this.nLayers = nLayers;
    this.transforms = transformations;

    // see TwoCameraSphericalMaxProjection.initSphericalMaximumProjection
    int aperture = 90 / nAngles;

    if (saveOutput) {
      if (!outputdir.exists()) outputdir.mkdirs();

      smp.saveSphere(new File(outputdir, "Sphere.obj").getAbsolutePath());
    }

    Point3f center = smp.getCenter();

    weights = new FusionWeight[2][2][nAngles];

    for (int a = 0; a < nAngles; a++) {
      Point3f cen = new Point3f(center);
      if (transforms[a] != null) transforms[a].transform(cen);
      weights[CAMERA1][LEFT][a] =
          new AngleWeighter2(AngleWeighter2.X_AXIS, 135, aperture, new Point3f(cen));
      weights[CAMERA1][RIGHT][a] =
          new AngleWeighter2(AngleWeighter2.X_AXIS, -135, aperture, new Point3f(cen));
      weights[CAMERA2][LEFT][a] =
          new AngleWeighter2(AngleWeighter2.X_AXIS, 45, aperture, new Point3f(cen));
      weights[CAMERA2][RIGHT][a] =
          new AngleWeighter2(AngleWeighter2.X_AXIS, -45, aperture, new Point3f(cen));
    }
  }
  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());
    }
  }