Merge changes I561ba44b,Icaebd98e,Ic0bd4afc,Ia0f98434 into sc-dev
* changes: Move Wu check for max colors earlier. Ignore transparent pixels during WSMeans Fix create colors in Wu quantizer Fix initializing clusters with random randoms
This commit is contained in:
@@ -22,20 +22,19 @@ import java.util.Random;
|
||||
* Represents a centroid in Kmeans algorithms.
|
||||
*/
|
||||
public class Mean {
|
||||
private static final Random RANDOM = new Random(0);
|
||||
|
||||
public float[] center;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param upperBound maximum value of a dimension in the space Kmeans is optimizing in
|
||||
* @param random used to generate a random center
|
||||
*/
|
||||
Mean(int upperBound) {
|
||||
Mean(int upperBound, Random random) {
|
||||
center =
|
||||
new float[]{
|
||||
RANDOM.nextInt(upperBound + 1), RANDOM.nextInt(upperBound + 1),
|
||||
RANDOM.nextInt(upperBound + 1)
|
||||
random.nextInt(upperBound + 1), random.nextInt(upperBound + 1),
|
||||
random.nextInt(upperBound + 1)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
@@ -57,13 +58,27 @@ public class WSMeansQuantizer implements Quantizer {
|
||||
}
|
||||
|
||||
if (maxColors > means.length) {
|
||||
// Always initialize Random with the same seed. Ensures the results of quantization
|
||||
// are consistent, even when random centroids are required.
|
||||
Random random = new Random(0x42688);
|
||||
int randomMeansToCreate = maxColors - means.length;
|
||||
for (int i = 0; i < randomMeansToCreate; i++) {
|
||||
mMeans[means.length + i] = new Mean(100);
|
||||
mMeans[means.length + i] = new Mean(100, random);
|
||||
}
|
||||
}
|
||||
|
||||
for (int pixel : pixels) {
|
||||
// These are pixels from the bitmap that is being quantized.
|
||||
// Depending on the bitmap & downscaling, it may have pixels that are less than opaque
|
||||
// Ignore those pixels.
|
||||
///
|
||||
// Note: they don't _have_ to be ignored, for example, we could instead turn them
|
||||
// opaque. Traditionally, including outside Android, quantizers ignore transparent
|
||||
// pixels, so that strategy was chosen.
|
||||
int alpha = (pixel >> 24);
|
||||
if (alpha < 255) {
|
||||
continue;
|
||||
}
|
||||
Integer currentCount = mCountByColor.get(pixel);
|
||||
if (currentCount == null) {
|
||||
currentCount = 0;
|
||||
@@ -105,8 +120,12 @@ public class WSMeansQuantizer implements Quantizer {
|
||||
/** Create random starting centroids for K-means. */
|
||||
public static float[][] randomMeans(int maxColors, int upperBound) {
|
||||
float[][] means = new float[maxColors][];
|
||||
|
||||
// Always initialize Random with the same seed. Ensures the results of quantization
|
||||
// are consistent, even when random centroids are required.
|
||||
Random random = new Random(0x42688);
|
||||
for (int i = 0; i < maxColors; i++) {
|
||||
means[i] = new Mean(upperBound).center;
|
||||
means[i] = new Mean(upperBound, random).center;
|
||||
}
|
||||
return means;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,12 @@ public class WuQuantizer implements Quantizer {
|
||||
// All of the sample Wu implementations are reimplementations of a snippet of C code from
|
||||
// the early 90s. They all cap the maximum # of colors at 256, and it is impossible to tell
|
||||
// if this is a requirement, a consequence of QUANT_SIZE, or arbitrary.
|
||||
this.mMaxColors = Math.min(MAX_COLORS, maxColorCount);
|
||||
//
|
||||
// Also, the number of maximum colors should be capped at the number of pixels - otherwise,
|
||||
// If extraction is run on a set of pixels whose count is less than max colors,
|
||||
// then colors.length < max colors, and accesses to colors[index] throw an
|
||||
// ArrayOutOfBoundsException.
|
||||
this.mMaxColors = Math.min(Math.min(MAX_COLORS, maxColorCount), colors.length);
|
||||
Box[] cube = new Box[mMaxColors];
|
||||
int red, green, blue;
|
||||
|
||||
@@ -119,17 +124,13 @@ public class WuQuantizer implements Quantizer {
|
||||
}
|
||||
}
|
||||
|
||||
// If extraction is run on a set of pixels whose count is less than the
|
||||
// number of max colors, then colors.length < max colors, and accesses
|
||||
// to colors[index] inside the for loop throw an ArrayOutOfBoundsException.
|
||||
int numColorsToCreate = (int) Math.min(mMaxColors, colors.length);
|
||||
for (k = 0; k < numColorsToCreate; ++k) {
|
||||
for (k = 0; k < mMaxColors; ++k) {
|
||||
weight = getVolume(cube[k], mWt);
|
||||
if (weight > 0) {
|
||||
red = (int) (getVolume(cube[k], mMr) / weight);
|
||||
green = (int) (getVolume(cube[k], mMg) / weight);
|
||||
blue = (int) (getVolume(cube[k], mMb) / weight);
|
||||
colors[k] = ((red & 0x0ff) << 16) | ((green & 0x0ff) << 8) | (blue & 0x0ff);
|
||||
colors[k] = (255 << 24) | (red << 16) | (green << 8) | blue;
|
||||
} else {
|
||||
colors[k] = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user