/**
   * Extract dense features across the training set. Then clusters are found within those features.
   */
  private AssignCluster<double[]> computeClusters() {
    System.out.println("Image Features");

    // computes features in the training image set
    features.reset();
    for (String scene : train.keySet()) {
      List<String> imagePaths = train.get(scene);
      System.out.println("   " + scene);

      for (String path : imagePaths) {
        ImageUInt8 image = UtilImageIO.loadImage(path, ImageUInt8.class);
        describeImage.process(image, features, null);
      }
    }
    // add the features to the overall list which the clusters will be found inside of
    for (int i = 0; i < features.size; i++) {
      cluster.addReference(features.get(i));
    }

    System.out.println("Clustering");
    // Find the clusters.  This can take a bit
    cluster.process(NUMBER_OF_WORDS);

    UtilIO.save(cluster.getAssignment(), CLUSTER_FILE_NAME);

    return cluster.getAssignment();
  }
  /**
   * Process all the data in the training data set to learn the classifications. See code for
   * details.
   */
  public void learnAndSave() {
    System.out.println("======== Learning Classifier");

    // Either load pre-computed words or compute the words from the training images
    AssignCluster<double[]> assignment;
    if (new File(CLUSTER_FILE_NAME).exists()) {
      assignment = UtilIO.load(CLUSTER_FILE_NAME);
    } else {
      System.out.println(" Computing clusters");
      assignment = computeClusters();
    }

    // Use these clusters to assign features to words
    FeatureToWordHistogram_F64 featuresToHistogram =
        new FeatureToWordHistogram_F64(assignment, HISTOGRAM_HARD);

    // Storage for the work histogram in each image in the training set and their label
    List<HistogramScene> memory;

    if (!new File(HISTOGRAM_FILE_NAME).exists()) {
      System.out.println(" computing histograms");
      memory = computeHistograms(featuresToHistogram);
      UtilIO.save(memory, HISTOGRAM_FILE_NAME);
    }
  }