-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpixelated_kmeans.pde
157 lines (130 loc) · 4.08 KB
/
pixelated_kmeans.pde
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
PImage img;
int pointCount = 100;
int centCount = 5;
int voxelSize = 20;
int xMax, yMax;
ArrayList<Column> columns;
Point[] centroids = new Point[centCount]; // ARRAY of rgb triplets
Point[][] points2d = new Point[500][500]; // CONTAINS indices into centroids[] array
int[][] pbn;
void setup() {
frameRate(1);
size(500, 500);
xMax = width/voxelSize;
yMax = height/voxelSize;
pbn = new int[xMax][yMax];
img = loadImage("birb.jpg");
img.resize(500, 0);
for (int x = 0; x < 500; x++) { //creating the points
for (int y = 0; y < 500; y++) {
points2d[x][y] = new Point(red(img.get(x, y)), green(img.get(x, y)), blue(img.get(x, y)));
}
}
for (int ce = 0; ce < centroids.length; ce++) { //creating the centroids
color imgget = img.get(round(random(0, 500)), round(random(0, 500)));
centroids[ce] = new Point(red(imgget), green(imgget), blue(imgget));
}
assign(); //initially assigning points to centroids
noLoop();
}
void draw() {
// pure display
for (int x = 0; x < 500; x++) {
for (int y = 0; y < 500; y++) {
points2d[x][y].display(x, y);
}
}
//APPLYING K-MEANS
boolean changed = true;
while (changed) {
for (int cent = 0; cent < centroids.length; cent++) { // recalculate centroid means
findMeans();
}
changed = assign(); //reassign points to centroids
}
//VOXELIZING
columns = new ArrayList<Column>();
int numRows = width / voxelSize;
int numColumns = height / voxelSize;
for (int x = 0; x < numColumns; x++) {
color[] voxelList = new color[numRows];
for (int y = 0; y < numRows; y++) {
int centroid = points2d[x * voxelSize][y * voxelSize].myCentroidIndex;
color c = color(centroids[centroid].r, centroids[centroid].g, centroids[centroid].b);
voxelList[y] = c;
}
Column c = new Column(x, voxelList);
columns.add(c);
}
for (Column c : columns) {
c.displayColumn(); //draw the columns of voxels
}
//building pbn
PBN();
}
boolean assign() {
boolean changed = false;
for (int x = 0; x < 500; x++) {
for (int y = 0; y <500; y++) {
int oldCentroid = points2d[x][y].myCentroidIndex;
float id = 1000000;
for (int c = 0; c < centroids.length; c++) {
float d = dist(points2d[x][y].r, points2d[x][y].g, points2d[x][y].b, centroids[c].r, centroids[c].g, centroids[c].b);
if (d < id) {
points2d[x][y].myCentroidIndex = c;
id = dist(points2d[x][y].r, points2d[x][y].g, points2d[x][y].b, centroids[c].r, centroids[c].g, centroids[c].b);
}
}
if (points2d[x][y].myCentroidIndex != oldCentroid)
changed = true;
}
}
return changed;
}
void findMeans() {
float sumR[] = new float[centCount];
float sumG[] = new float[centCount];
float sumB[] = new float[centCount];
float total[] = new float[centCount];
for (int x = 0; x < 500; x++) {
for (int y = 0; y < 500; y++) {
Point pgp = points2d[x][y];
sumR[pgp.myCentroidIndex] += pgp.r;
sumG[pgp.myCentroidIndex] += pgp.g;
sumB[pgp.myCentroidIndex] += pgp.b;
total[pgp.myCentroidIndex] += 1;
}
}
for (int c = 0; c < centroids.length; c++) {
centroids[c].r = sumR[c] / total[c];
centroids[c].g = sumG[c] / total[c];
centroids[c].b = sumB[c] / total[c];
}
}
void PBN() {
int colCount = 0;
HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
//for each voxel, making the HashMap
for (int x = 0; x < xMax; x++) {
for (int y = 0; y < yMax; y++) {
// nothing about what's on the screen is reliable
// find color of underlying point's CENTROID
int centroid = points2d[x * voxelSize][y * voxelSize].myCentroidIndex;
color c = color(centroids[centroid].r, centroids[centroid].g, centroids[centroid].b);
if (!hm.containsKey(c)) {
hm.put(c, colCount);
colCount++;
}
pbn[x][y] = hm.get(c);
}
}
for (int y = 0; y < pbn.length; y++) {
for (int x = 0; x < pbn[0].length; x++) {
//if (frameCount > 5 && colCount == centCount) {
print(pbn[x][y] + " ");
//}
}
println();
}
println();
}