Esempio n. 1
0
  /**
   * Find the most likely person based on a detection. Returns the index, and stores the confidence
   * value into pConfidence.
   *
   * @param projectedTestFace the projected test face
   * @param pConfidencePointer a pointer containing the confidence value
   * @param iTestFace the test face index
   * @return the index
   */
  private int findNearestNeighbor(float projectedTestFace[], FloatPointer pConfidencePointer) {
    double leastDistSq = Double.MAX_VALUE;
    int i = 0;
    int iTrain = 0;
    int iNearest = 0;

    LOGGER.info("................");
    LOGGER.info("find nearest neighbor from " + nTrainFaces + " training faces");
    for (iTrain = 0; iTrain < nTrainFaces; iTrain++) {
      // LOGGER.info("considering training face " + (iTrain + 1));
      double distSq = 0;

      for (i = 0; i < nEigens; i++) {
        // LOGGER.debug("  projected test face distance from eigenface " + (i + 1) + " is " +
        // projectedTestFace[i]);

        float projectedTrainFaceDistance = (float) projectedTrainFaceMat.get(iTrain, i);
        float d_i = projectedTestFace[i] - projectedTrainFaceDistance;
        distSq +=
            d_i
                * d_i; // / eigenValMat.data_fl().get(i);  // Mahalanobis distance (might give
                       // better results than Eucalidean distance)
        //          if (iTrain < 5) {
        //            LOGGER.info("    ** projected training face " + (iTrain + 1) + " distance from
        // eigenface " + (i + 1) + " is " + projectedTrainFaceDistance);
        //            LOGGER.info("    distance between them " + d_i);
        //            LOGGER.info("    distance squared " + distSq);
        //          }
      }

      if (distSq < leastDistSq) {
        leastDistSq = distSq;
        iNearest = iTrain;
        LOGGER.info(
            "  training face "
                + (iTrain + 1)
                + " is the new best match, least squared distance: "
                + leastDistSq);
      }
    }

    // Return the confidence level based on the Euclidean distance,
    // so that similar images should give a confidence between 0.5 to 1.0,
    // and very different images should give a confidence between 0.0 to 0.5.
    float pConfidence =
        (float) (1.0f - Math.sqrt(leastDistSq / (float) (nTrainFaces * nEigens)) / 255.0f);
    pConfidencePointer.put(pConfidence);

    LOGGER.info(
        "training face " + (iNearest + 1) + " is the final best match, confidence " + pConfidence);
    return iNearest;
  }