Пример #1
0
  private static List<DistrPair> prepareDistribution(Segment[] segments, Photo photo) {
    List<DistrPair> distribution = new ArrayList<>();
    int area = photo.getWidth() * photo.getHeight();
    double sum = 0;
    for (Segment seg : segments) {
      DistrPair dp = new DistrPair();
      //            dp.weight = (double)seg.getSumPixels() / area;
      /* Original method uses sqrt */
      dp.weight = Math.sqrt((double) seg.getSumPixels() / area);
      sum += dp.weight;
      Vector vect = new Vector(14);
      Addterator<Float> addter = vect.addterator();

      /* Color moments - 9 elements in total */
      float[] mean_hsb = seg.getMean();
      float[] stdev_hsb = seg.getStdDeviation();
      float[] skew_hsb = seg.getSkewness();
      for (int i = 0; i < Segment.MODEL_NUM_ELEMENTS; i++) {
        addter.add(mean_hsb[i]);
        addter.add(stdev_hsb[i]);
        addter.add(skew_hsb[i]);
      }
      /* The other elements - another 5 of them */
      int o_width = seg.getRight() - seg.getLeft();
      o_width = Math.max(o_width, 1);
      int o_height = seg.getBottom() - seg.getTop();
      o_height = Math.max(o_height, 1);
      int o_area = o_width * o_height;
      /* 5 elements characterizing the shape of one segment */
      addter.add((float) Math.log((double) o_width / o_height + 1));
      addter.add((float) Math.log((double) o_area / area + 1));
      addter.add((float) seg.getSumPixels() / o_area);
      addter.add((float) seg.getX() / photo.getWidth());
      addter.add((float) seg.getY() / photo.getHeight());

      dp.vector = vect;
      distribution.add(dp);
    }
    /* Scale the sum of weights to be 1 */
    for (DistrPair distrPair : distribution) {
      distrPair.weight /= sum;
    }
    return distribution;
  }
Пример #2
0
  /**
   * For given two photos, count their similarity. The result is from interval [0;1], 1 means
   * perfect match, 0 totaly different.
   *
   * @param photo1 First photo.
   * @param photo2 Second photo.
   * @return Similarity of given photos from interval [0;1];
   * @throws com.kappa_labs.ohunter.lib.net.OHException When Photos are wrongly set.
   */
  public static synchronized float computeSimilarity(Photo photo1, Photo photo2)
      throws OHException {
    float ret = 0;

    /* Scale the images to provide the best results */
    try {
      photo1.sImage = photo1._sImage = new SImage(photo1.sImage);
      photo2.sImage = photo2._sImage = new SImage(photo2.sImage);

      ((SImage) photo1.sImage).setImage(resize(((SImage) photo1._sImage).toBufferedImage()));
      ((SImage) photo2.sImage).setImage(resize(((SImage) photo2._sImage).toBufferedImage()));
    } catch (Exception e) {
      LOGGER.log(Level.WARNING, "Could not acquire photos from client: {0}", e);
      throw new OHException("Could not acquire photos!", OHException.EXType.OTHER);
    }

    /* Count average from few attempts */
    final int numRepeats = settingsManager.getSimilarityNumberOfRepeats();
    int iteration = numRepeats;
    while (iteration-- > 0) {
      /* Perform segmentation */
      Segment[] segments1 = Segmenter.findSegments(photo1);
      Segment[] segments2 = Segmenter.findSegments(photo2);
      LOGGER.log(
          Level.FINER,
          "... got {0} segments from first and {1} segments" + " in the second photo",
          new Object[] {segments1.length, segments2.length});

      /* Create new Problem from given counted segments */
      Problem problem = new Problem();
      problem.distr1 = prepareDistribution(segments1, photo1);
      problem.distr2 = prepareDistribution(segments2, photo2);

      /* Solve the EMP linear problem and return the final result */
      EMDSolver empm = new EMDSolver(problem);
      float act = Math.max(0f, Math.min(1f, (float) empm.countValue()));
      LOGGER.finer(String.format(" - similarity: %.1f%%", 100 - act * 100));
      ret += act;
    }
    ret /= numRepeats;

    return 1f - ret;
  }