Thursday, August 18, 2011

Conclusion

Due to time constraints, our team was not able to submit a quality crater detector. But this exercise proved a useful introduction to image classification.

Sunday, June 26, 2011

Candidate Features

  1. Circle fitting - a measure of how likely it is that a circle is present, centered, and contained in the window
  2. Average rgb value in window *
  3. Variance in window - a measure of contrast
  4. Darkness in window - percentage of pixels with rgb value below a threshold *
  5. Quadrants - average rgb values of four quadrants *
* Normalize to average rgb of surroundings

Saturday, June 25, 2011

Circle Fitting

One method for finding craters is fitting circles to the resulting edges from running a Canny Edge Detector on the image. The first step is to run the Canny Edge Detector on the data. The result is shown in red.

The next step is to perform circle fitting with the resulting pixels (edges) from Canny. We use the Taubin method for circle fitting. The circles are shown in magenta.

Note: the two images above were generated with different Canny thresholds; we need to come up with a way to choose the threshold. Perhaps we can use PatternExplorer to help us decide what this parameter should be a function of.

Running JBoost on Windows 7

Notes:
  1. Provided Python scripts are for Python 2
  2. The correct usage for nfold.py is found in the file nfold.py, not the JBoost website
  3. CLASSPATH entries with directories or file names containing spaces should be enclosed with ""

Java Code: Running Average

Following is Java code for calculating a running average and variance. This is useful if the sum of all elements causes overflow, or if a "live" calculation is required.

private double computeVariance(int[] stream) {
double mean = computeAverage(stream);
double rvar = Math.pow(stream[0] - mean, 2);
double total = 1;
double fract = 1;
double sqdif = 0;
for (int i = 1; i < stream.length; i++) {
sqdif = Math.pow(stream[i] - mean, 2);
fract = total / ++total;
rvar = (rvar * fract) + (sqdif / total);
}
return rvar;
}

private double computeAverage(int[] stream) {
double rmean = stream[0];
double total = 1;
double fract = 1;
for (int i = 1; i < stream.length; i++) {
fract = total / ++total;
rmean = (rmean * fract) + (stream[i] / total);
}
return rmean;
}

Thursday, June 23, 2011

Generating Negative Examples

To improve the performance of the classifier, we generate negative examples. The following strategy takes negative examples from the eight non-overlapping windows surrounding the positive example, and equal to the positive example's dimensions. The result is shown below. Positive examples are shown in yellow, and suggested negatives in red:

An LRO image with suggested negative examples.

An A15 image with suggested negative examples.

The advantages of this strategy are:
  • 8-1 negative to positive example ratio
  • Less computationally expensive than random or full sliding widow
  • All sizes of examples
  • Learn the classifier not to mistake the surroundings of a crater for a crater
Disadvantages:
  • May overfit due to training negative examples only on the sizes of positive training examples
  • Negative examples sometimes coincide with positive ones (this can be fixed)

Another strategy: Slide a window over the image in small increments and label all that don't coincide greatly with positive examples as negative.

Label Boxes

We write Java routines for processing the positive label tags and drawing bounding boxes on the training images:

LRO image with positive examples labeled.

LRO image with some positive examples labeled.

A15 image with positive examples labeled.
To avoid Java's ImageIO.write(..) flattening rectangle colors, the images are all converted to maximum quality JPEG files using Photoshop batch processing. This problem is addressed in this StackOverflow post.

The contest rules specify minimum and maximum crater sizes. The larger A15 images appear to have nearly all possible craters labeled, while the smaller LRO images in the training set do not. An explanation is that the training data is simply meant to provide positive instances. This suggests that image resolution is not a good predictor for the number of craters, and that clearly unlabeled craters should not be used as negative training examples.

The most apparent distinguishing features are circular shape and strong contrast gradient. The light source is primarily from the right, but there are no guarantees about the test data. To generalize the classifier, an idea is to train the classifier on rotated versions of the image.

Wednesday, June 22, 2011

Java Advanced Imaging

JAI is required to procss TIFF files in Java. This isn't necessary for the classifier because the input for test images is an int array, but might come in handy later. To install JAI on Windows:

  1. Grab this executable
  2. Follow the installer instructions
  3. Official instructions are here
  4. The API docs for JAI are here
Question: To avoid using the JAI just for the sake of importing TIFFs, how to convert TIFFs to a format usable by the ImageIO package (e.g. jpg, png) and preserve exact pixel values?

Initial Ideas

  • Use Java
  • PatternExplorer to see differences in craters over the A15 and LRO images
  • Different classifiers for A15 and LRO images:
    • Weka
    • AdaBoost
    • Generate Java code for a classifier that can be "pasted" into the solution.
  • Preprocessing:
    • Will need to reproduce all features used in the training process?
  • There are 2 cores on the host machine, so how to parallelize?