1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math4.examples.kmeans.image;
19
20 import java.util.concurrent.Callable;
21 import java.time.Instant;
22 import java.time.Duration;
23
24 import picocli.CommandLine;
25 import picocli.CommandLine.Option;
26 import picocli.CommandLine.Command;
27
28 import org.apache.commons.rng.UniformRandomProvider;
29 import org.apache.commons.rng.simple.RandomSource;
30 import org.apache.commons.math4.legacy.ml.distance.DistanceMeasure;
31 import org.apache.commons.math4.legacy.ml.distance.EuclideanDistance;
32 import org.apache.commons.math4.legacy.ml.clustering.Clusterer;
33 import org.apache.commons.math4.legacy.ml.clustering.KMeansPlusPlusClusterer;
34 import org.apache.commons.math4.legacy.ml.clustering.ElkanKMeansPlusPlusClusterer;
35
36
37
38
39 @Command(description = "Run the application",
40 mixinStandardHelpOptions = true)
41 public final class StandAlone implements Callable<Void> {
42
43 @Option(names = { "-k" }, paramLabel = "K", required = true,
44 description = "Number of clusters.")
45 private int numClusters;
46
47 @Option(names = { "-i", "--iterations" }, paramLabel = "N",
48 description = "Allowed number of iterations (default: ${DEFAULT-VALUE}).")
49 private int maxIter = 2000;
50
51 @Option(names = { "--image" }, paramLabel = "FILE", required = true,
52 description = "Input file name.")
53 private String inputFile;
54
55 @Option(names = { "-o", "--output" }, paramLabel = "PREFIX", required = true,
56 description = "Prefix (path) for the output files.")
57 private String outputPrefix;
58
59
60
61
62
63
64 public static void main(String[] args) {
65 CommandLine.call(new StandAlone(), args);
66 }
67
68 @Override
69 public Void call() {
70 final ImageData image = ImageData.load(inputFile);
71 final UniformRandomProvider rng = RandomSource.MWC_256.create();
72 final DistanceMeasure distance = new EuclideanDistance();
73
74 cluster(image,
75 new ElkanKMeansPlusPlusClusterer<>(numClusters,
76 maxIter,
77 distance,
78 rng),
79 "elkan");
80 cluster(image,
81 new KMeansPlusPlusClusterer<>(numClusters,
82 maxIter,
83 distance,
84 rng),
85 "kmeans");
86
87 return null;
88 }
89
90
91
92
93
94
95
96
97 private void cluster(ImageData image,
98 Clusterer<ImageData.PixelClusterable> algo,
99 String id) {
100 final String dot = ".";
101 final String out = new StringBuilder()
102 .append(outputPrefix)
103 .append(dot)
104 .append("k_")
105 .append(numClusters)
106 .append(dot)
107 .append(id)
108 .append(dot)
109 .toString();
110
111 final Instant start = Instant.now();
112 image.write(algo.cluster(image.getPixels()), out);
113
114 System.out.println("time=" + Duration.between(start, Instant.now()).toMillis());
115
116 }
117 }