private FloatCentroidsResult cluster(List<FloatLocalFeatureAdaptor<?>> rawData) { // build full data array final float[][] vectors = new float[rawData.size()][]; for (int i = 0; i < vectors.length; i++) { vectors[i] = rawData.get(i).getFeatureVector().values; } // Perform clustering final FloatKMeans kmeans = FloatKMeans.createExact(numVladCentroids, numIterations); final FloatCentroidsResult centroids = kmeans.cluster(vectors); return centroids; } }
private FloatKMeans newFloatKMeans(int K) { KMeansConfiguration<FloatNearestNeighbours, float[]> newConf = conf.clone(); newConf.setK(K); return new FloatKMeans(newConf); } }
@Override public Result cluster(DataSource<float[]> ds) { try { Result result = cluster(ds, conf.K); result.nn = conf.factory.create(result.centroids); return result; } catch (Exception e) { throw new RuntimeException(e); } }
@Override public List<? extends PixelSet> segment(final MBFImage image) { final MBFImage input = ColourSpace.convert(image, colourSpace); final float[][] imageData = imageToVector(input); final FloatCentroidsResult result = kmeans.cluster(imageData); final List<PixelSet> out = new ArrayList<PixelSet>(kmeans.getConfiguration().getK()); for (int i = 0; i < kmeans.getConfiguration().getK(); i++) out.add(new PixelSet()); final HardAssigner<float[], ?, ?> assigner = result.defaultHardAssigner(); final int height = image.getHeight(); final int width = image.getWidth(); for (int y = 0, i = 0; y < height; y++) { for (int x = 0; x < width; x++, i++) { final float[] pixel = imageData[i]; final int centroid = assigner.assign(pixel); out.get(centroid).addPixel(x, y); } } return out; } }
} else { for (int d=0; d < D; ++d) { float newValue = (float)((float)roundFloat((double)centroids_accum[k][d] / (double)new_counts[k]));
/** * Main clustering algorithm. A number of threads as specified are * started each containing an assignment job and a reference to * the same set of FloatNearestNeighbours object (i.e. Exact or KDTree). * Each thread is added to a job pool and started in parallel. * A single accumulator is shared between all threads and locked on update. * <br/> * This methods expects that the initial centroids have already been set in * the <code>result</code> object and as such <strong>ignores</strong> the * init object. <strong>In normal operation you should call one of the other <code>cluster</code> * cluster methods instead of this one.</strong> However, if you wish to resume clustering * iterations from a result that you've already generated this is the method * to use. * * @param data the data to be clustered * @param result the results object to be populated * @throws InterruptedException if interrupted while waiting, in * which case unfinished tasks are cancelled. */ public void cluster(float[][] data, Result result) throws InterruptedException { DataSource<float[]> ds = new FloatArrayBackedDataSource(data, rng); cluster(ds, result); }
@Override public List<? extends PixelSet> segment(final MBFImage image) { final MBFImage input = ColourSpace.convert(image, colourSpace); final float[][] imageData = imageToVector(input); final FloatCentroidsResult result = kmeans.cluster(imageData); final List<PixelSet> out = new ArrayList<PixelSet>(kmeans.getConfiguration().getK()); for (int i = 0; i < kmeans.getConfiguration().getK(); i++) out.add(new PixelSet()); final HardAssigner<float[], ?, ?> assigner = result.defaultHardAssigner(); final int height = image.getHeight(); final int width = image.getWidth(); for (int y = 0, i = 0; y < height; y++) { for (int x = 0; x < width; x++, i++) { final float[] pixel = imageData[i]; final int centroid = assigner.assign(pixel); out.get(centroid).addPixel(x, y); } } return out; } }
final FloatKMeans kmeans = FloatKMeans.createExact(K, 100); final FloatNearestNeighboursProvider centroids = (FloatNearestNeighboursProvider) kmeans.cluster(tmp);
@Override public Result cluster(float[][] data) { DataSource<float[]> ds = new FloatArrayBackedDataSource(data, rng); try { Result result = cluster(ds, conf.K); result.nn = conf.factory.create(result.centroids); return result; } catch (Exception e) { throw new RuntimeException(e); } }
/** * Convenience method to quickly create an exact {@link FloatKMeans}. All * parameters other than the number of clusters are set * at their defaults, but can be manipulated through the configuration * returned by {@link #getConfiguration()}. * <p> * Euclidean distance is used to measure the distance between points. * * @param K * the number of clusters * @return a {@link FloatKMeans} instance configured for exact k-means */ public static FloatKMeans createExact(int K) { final KMeansConfiguration<FloatNearestNeighbours, float[]> conf = new KMeansConfiguration<FloatNearestNeighbours, float[]>(K, new FloatNearestNeighboursExact.Factory()); return new FloatKMeans(conf); }
private FloatCentroidsResult clusterPixels(MBFImage toDraw) { final float[][] testP = toDraw.getBand(0).pixels; float sum = 0; for (int i = 0; i < testP.length; i++) for (int j = 0; j < testP[i].length; j++) sum += testP[i][j]; if (sum == 0) return null; final FloatKMeans k = FloatKMeans.createExact(3, 2); final float[][] imageData = toDraw.getPixelVectorNative(new float[toDraw.getWidth() * toDraw.getHeight() * 3][3]); return k.cluster(imageData); } }
/** * Initiate clustering with the given data and number of clusters. * Internally this method constructs the array to hold the centroids * and calls {@link #cluster(DataSource, float [][])}. * * @param data data source to cluster with * @param K number of clusters to find * @return cluster centroids */ protected Result cluster(DataSource<float[]> data, int K) throws Exception { int D = data.numDimensions(); Result result = new Result(); result.centroids = new float[K][D]; init.initKMeans(data, result.centroids); cluster(data, result); return result; }
/** * Convenience method to quickly create an approximate {@link FloatKMeans} * using an ensemble of KD-Trees to perform nearest-neighbour lookup. All * parameters other than the number of clusters are set * at their defaults, but can be manipulated through the configuration * returned by {@link #getConfiguration()}. * <p> * Euclidean distance is used to measure the distance between points. * * @param K * the number of clusters * @return a {@link FloatKMeans} instance configured for approximate k-means * using an ensemble of KD-Trees */ public static FloatKMeans createKDTreeEnsemble(int K) { final KMeansConfiguration<FloatNearestNeighbours, float[]> conf = new KMeansConfiguration<FloatNearestNeighbours, float[]>(K, new FloatNearestNeighboursKDTree.Factory()); return new FloatKMeans(conf); }
final FloatKMeans km = FloatKMeans.createExact(50); final FloatCentroidsResult result = km.cluster(vectors.toArray(new float[vectors.size()][]));
@Override public int[][] performClustering(float[][] data) { FloatCentroidsResult clusters = this.cluster(data); return new IndexClusters(clusters.defaultHardAssigner().assign(data)).clusters(); }
/** * Convenience method to quickly create an exact {@link FloatKMeans}. All * parameters other than the number of clusters and number * of iterations are set at their defaults, but can be manipulated through * the configuration returned by {@link #getConfiguration()}. * <p> * Euclidean distance is used to measure the distance between points. * * @param K * the number of clusters * @param niters * maximum number of iterations * @return a {@link FloatKMeans} instance configured for exact k-means */ public static FloatKMeans createExact(int K, int niters) { final KMeansConfiguration<FloatNearestNeighbours, float[]> conf = new KMeansConfiguration<FloatNearestNeighbours, float[]>(K, new FloatNearestNeighboursExact.Factory(), niters); return new FloatKMeans(conf); }
final FloatKMeans km = FloatKMeans.createExact(50); final FloatCentroidsResult result = km.cluster(vectors.toArray(new float[vectors.size()][]));
/** * Compute HierarchicalFloatKMeans clustering. * * @param data Data to cluster. * @param K Number of clusters for this node. * @param height Tree height. * * @return a new HierarchicalFloatKMeans node representing a sub-clustering. **/ private Node trainLevel(final float[][] data, int K, int height) { Node node = new Node(); node.children = (height == 1) ? null : new Node[K]; FloatKMeans kmeans = newFloatKMeans(K); node.result = kmeans.cluster(data); HardAssigner<float[], float[], IntFloatPair> assigner = node.result.defaultHardAssigner(); if (height > 1) { int[] ids = assigner.assign(data); for (int k = 0; k < K; k++) { float[][] partition = extractSubset(data, ids, k); int partitionK = Math.min(K, partition.length); node.children[k] = trainLevel(partition, partitionK, height - 1); } } return node; }
/** * Construct using the given colour space, number of segments, and distance * measure. The elements of each colour band are by the corresponding * elements in the given scaling vector, and the k-means algorithm will * iterate at most <code>maxIters</code> times. * * @param colourSpace * the colour space * @param scaling * the scaling vector * @param K * the number of segments * @param distance * the distance measure * @param maxIters * the maximum number of iterations to perform */ public KMColourSegmenter(ColourSpace colourSpace, float[] scaling, int K, FloatFVComparator distance, int maxIters) { if (scaling != null && scaling.length < colourSpace.getNumBands()) throw new IllegalArgumentException( "Scaling vector must have the same length as the number of dimensions of the target colourspace (or more)"); this.colourSpace = colourSpace; this.scaling = scaling; final KMeansConfiguration<FloatNearestNeighbours, float[]> conf = new KMeansConfiguration<FloatNearestNeighbours, float[]>( K, new FloatNearestNeighboursExact.Factory(distance), maxIters); this.kmeans = new FloatKMeans(conf); }
final FloatKMeans cluster = FloatKMeans.createExact(3, 2); final FloatCentroidsResult result = cluster.cluster(imageData);