MCPcopy Create free account
hub / github.com/ARM-software/astc-encoder / kmeans_init

Function kmeans_init

Source/astcenc_find_best_partitioning.cpp:60–135  ·  view source on GitHub ↗

* @brief Pick some initial kmeans cluster centers. * * @param blk The image block color data to compress. * @param texel_count The number of texels in the block. * @param partition_count The number of partitions in the block. * @param[out] cluster_centers The initial partition cluster center colors. */

Source from the content-addressed store, hash-verified

58 * @param[out] cluster_centers The initial partition cluster center colors.
59 */
60static void kmeans_init(
61 const image_block& blk,
62 unsigned int texel_count,
63 unsigned int partition_count,
64 vfloat4 cluster_centers[BLOCK_MAX_PARTITIONS]
65) {
66 promise(texel_count > 0);
67 promise(partition_count > 0);
68
69 unsigned int clusters_selected = 0;
70 float distances[BLOCK_MAX_TEXELS];
71
72 // Pick a random sample as first cluster center; 145897 from random.org
73 unsigned int sample = 145897 % texel_count;
74 vfloat4 center_color = blk.texel(sample);
75 cluster_centers[clusters_selected] = center_color;
76 clusters_selected++;
77
78 // Compute the distance to the first cluster center
79 float distance_sum = 0.0f;
80 for (unsigned int i = 0; i < texel_count; i++)
81 {
82 vfloat4 color = blk.texel(i);
83 vfloat4 diff = color - center_color;
84 float distance = dot_s(diff * diff, blk.channel_weight);
85 distance_sum += distance;
86 distances[i] = distance;
87 }
88
89 // More numbers from random.org for weighted-random center selection
90 const float cluster_cutoffs[9] {
91 0.626220f, 0.932770f, 0.275454f,
92 0.318558f, 0.240113f, 0.009190f,
93 0.347661f, 0.731960f, 0.156391f
94 };
95
96 unsigned int cutoff = (clusters_selected - 1) + 3 * (partition_count - 2);
97
98 // Pick the remaining samples as needed
99 while (true)
100 {
101 // Pick the next center in a weighted-random fashion.
102 float summa = 0.0f;
103 float distance_cutoff = distance_sum * cluster_cutoffs[cutoff++];
104 for (sample = 0; sample < texel_count; sample++)
105 {
106 summa += distances[sample];
107 if (summa >= distance_cutoff)
108 {
109 break;
110 }
111 }
112
113 // Clamp to a valid range and store the selected cluster center
114 sample = astc::min(sample, texel_count - 1);
115
116 center_color = blk.texel(sample);
117 cluster_centers[clusters_selected++] = center_color;

Callers 1

Calls 3

texelMethod · 0.80
dot_sFunction · 0.70
minFunction · 0.70

Tested by

no test coverage detected