/*
* Copyright (c) 2021, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package boofcv.struct.kmeans;
import boofcv.concurrency.BoofConcurrency;
import boofcv.factory.struct.FactoryTupleDesc;
import boofcv.struct.feature.*;
import org.ddogleg.clustering.ComputeMeanClusters;
import org.ddogleg.clustering.ConfigKMeans;
import org.ddogleg.clustering.FactoryClustering;
import org.ddogleg.clustering.PointDistance;
import org.ddogleg.clustering.kmeans.StandardKMeans;
/**
* Factory for creating classes related to clustering of {@link TupleDesc} data structures
*
* @author Peter Abeles
*/
@SuppressWarnings("unchecked")
public class FactoryTupleCluster {
/**
* Creates a K-means clistering algorithm
*
* @param config Configuration for K-Means clustering
* @param minimumForThreads Performance tuning parameter. A single threaded variant is used if the number of descriptors is less than this number.
* @param numElements Number of elements in the tuple
* @param tupleType Type of tuple
* @return Clustering algorithm
*/
public static >
StandardKMeans | kmeans( ConfigKMeans config, int minimumForThreads, int numElements, Class | tupleType ) {
config.checkValidity();
if (BoofConcurrency.isUseConcurrent()) {
return FactoryClustering.kMeans_MT(config, minimumForThreads,
createMeanClusters(numElements, minimumForThreads, tupleType),
createDistance(tupleType),
() -> FactoryTupleDesc.createTuple(numElements, tupleType));
} else {
return FactoryClustering.kMeans(config,
createMeanClusters(numElements, minimumForThreads, tupleType),
createDistance(tupleType),
() -> FactoryTupleDesc.createTuple(numElements, tupleType));
}
}
public static | >
ComputeMeanClusters | createMeanClusters( int numElements, int minimumForThreads, Class | type ) {
if (type == TupleDesc_F64.class) {
if (BoofConcurrency.isUseConcurrent()) {
var mean = new ComputeMeanTuple_MT_F64(numElements);
mean.setMinimumForConcurrent(minimumForThreads);
return (ComputeMeanClusters | )mean;
} else {
return (ComputeMeanClusters | )new ComputeMeanTuple_F64();
}
} else if (type == TupleDesc_F32.class) {
if (BoofConcurrency.isUseConcurrent()) {
var mean = new ComputeMeanTuple_MT_F32(numElements);
mean.setMinimumForConcurrent(minimumForThreads);
return (ComputeMeanClusters | )mean;
} else {
return (ComputeMeanClusters | )new ComputeMeanTuple_F32();
}
} else if (type == TupleDesc_U8.class) {
if (BoofConcurrency.isUseConcurrent()) {
var mean = new ComputeMeanTuple_MT_U8(numElements);
mean.setMinimumForConcurrent(minimumForThreads);
return (ComputeMeanClusters | )mean;
} else {
return (ComputeMeanClusters | )new ComputeMeanTuple_U8(numElements);
}
} else if (type == TupleDesc_B.class) {
// if (BoofConcurrency.isUseConcurrent()) {
// var mean = new ComputeMeanTuple_MT_U8(numElements);
// mean.setMinimumForConcurrent(minimumForThreads);
// return (ComputeMeanClusters | )mean;
// } else {
return (ComputeMeanClusters | )new ComputeMedianTuple_B(numElements);
// }
}
throw new IllegalArgumentException("Unknown");
}
public static | >
PointDistance | createDistance(Class | tuple) {
if (tuple== TupleDesc_F64.class)
return (PointDistance | )new TuplePointDistanceEuclideanSq.F64();
else if (tuple == TupleDesc_F32.class)
return (PointDistance | )new TuplePointDistanceEuclideanSq.F32();
else if (tuple == TupleDesc_U8.class)
return (PointDistance | )new TuplePointDistanceEuclideanSq.U8();
else if (tuple == TupleDesc_B.class)
return (PointDistance | )new TuplePointDistanceHamming();
throw new IllegalArgumentException("Add appropriate distance");
}
}
|