-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathZoneDetection.pde
303 lines (247 loc) · 11.4 KB
/
ZoneDetection.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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
class ZoneDetection {
int X1, X2, Y1, Y2;
int divX; //el divisor del ancho para obtener el tamaño de cada zona
int divY; //el divisor del alto para obtener el tamaño cada zona
int zonas; //cantidad de zonas
PImage cam; //la imagen que entrega la camara
//el ancho y alto de la "zona de deteccion" de la imagen obtenida.
int detectionWidth; //el ancho de la imagen analizada sera menor que el ancho (640) de la imagen obtenida.
int detectionHeight; //el alto de la imagen analizada también será menor que el alto (480)
//el ancho y el alto de cada una de las áreas de evaluación de imagen
int interAreaWidth;
int interAreaHeight;
//Array de listas (int) que guardan posiciones de los pixelen por zona como punto de referencia
IntList [] pixelsRefZone;
//Array de listas (int) que guardan posiciones de los pixelen por zona en cada momento
IntList [] pixlesCurrentZone;
int [] zonesVariation; //Array de ints para almacenar las variaciones de cantidad de pixeles por zona
//Variables para almacenar el dato de la Zona definida como activa
int zonaActiva;
int zonaAnterior;
int indexZona;
ZoneDetection (int x1, int y1, int x2, int y2, int divisionWidth, int divisionHeight, PImage _cam) {
X1=x1; //posicion izquierda
Y1=y1; //posición superior de la pantalla
X2=x2; //posicion derecha
Y2=y2; //posicion inferior de la pantalla
divX = divisionWidth; //divisor del acho de la imagen para anchos zonales
divY = divisionHeight; //divisor del alto de la imagen para altos zonales
cam = _cam; //PImage donde se almacenaran las imagenes
//Tamaños de la zona de deteccion
detectionWidth = X2-X1;
detectionHeight = Y2-Y1;
//el ancho y el alto de cada una de las áreas de evaluación de imagen
interAreaWidth = detectionWidth / divX;
interAreaHeight = detectionHeight / divY;
zonas = (divX*divY);
pixelsRefZone = new IntList[ zonas ];
pixlesCurrentZone = new IntList[ zonas ];
zonesVariation = new int [zonas];
zonaActiva = 0; //inicializamos en 0 mientras aun no hay lectura de los pixeles
zonaAnterior = 0;
indexZona=0;
}
void readFilterCam () {
if (camara.available() == true) {
camara.read();
camara.filter(THRESHOLD, .5 );
}
}
void drawGrid () {
pushMatrix();
pushStyle();
rectMode (CORNERS);
noFill();
stroke (10, 120, 0);
strokeWeight (3);
rect (X1, Y1, X2, Y2);
translate (X1, Y1);
strokeWeight (1);
stroke (255,0,0);
for (int ty=0 ; ty < divY ; ty++) {
for (int tx=0 ; tx < divX ; tx++ ) {
if (ty != 0 ) line (interAreaWidth * tx, interAreaHeight *ty, interAreaWidth * (tx+1), interAreaHeight * ty);
if (tx != 0 ) line (interAreaWidth * tx, interAreaHeight *ty, interAreaWidth * (tx), interAreaHeight * (ty+1) );
}
}
popMatrix();
popStyle();
}
void calibrate () {
pushMatrix();
pushStyle();
rectMode (CORNERS);
cam.loadPixels(); //se llama antes de acceder al array de pixeles, diciendo "carga los pixeles, quiero acceder a ellos"
int i=0;
//For para recorrer cada una de las zonas de deteccion (recordar zonas = (divX*divY))
int cx=0;
int cy=0;
for ( int z=0 ; z < zonas ; z++) {
//Lista donde se almacenará temporalmente la posicion de los pixeles blancos de cada una
//de las zonas "z", desde 0 hasta el ultimo valor de z.
IntList listaZonaTemporal = new IntList();
//DEFINICION de variables definir los limites de cada una de las ZONAS a detectar
cx = z%divX; //la variable cx, queda en un loop entre 0 y el valor de "divX"
cy = (int) z/divX; //calcula cuantas lineas de X hay, es decir cuantos cuadros en el eje Y
int leftX = X1 + int (interAreaWidth * cx); //X1 es la distancia entre el borde iz de la imagen y el pixel iz desde donde comenzamos a detectar
int rightX = X1 + int (interAreaWidth * (cx+1) );
int upY = Y1 + int (interAreaHeight * cy ); //Y1 es la distancia entre el borde superior de la imagen y el pixel sup desde donde comenzamos a detectar
int bottomY = Y1 + int (interAreaHeight * (cy+1) );
//dos BUCLES anidados, para recorrer desde la iz-arriba hasta la der-abajo todos los pixeles de cada zona
for (int x = leftX ; x < rightX; x++) {
for (int y = upY; y < bottomY; y++) {
i = x + y * cam.width; //formula que calcula la posicion del pixel segun las posiciones X e Y
int v = cam.pixels[i] & 0xFF; // "v" almacena el valor en escala de grises del pixel
//RECORDAR que la imagen que se analiza fue filtrada para obtener solo blancos y negros
if (v == 255) { //si "v" es blanco ( es decir == 255)
listaZonaTemporal.append(i);//con .append agregamos la posición (i) del pixel a la lista temporal
}
}
}
//se almacenan los valores de "listaZonaTemporal" dentro del array de listas pixelsRefZone
//recordar: esta lista almacena la posicion de todos los pixeles blancos
pixelsRefZone[z] = listaZonaTemporal;
}
cam.updatePixels(); //esta funcion se llama despues de haber terminado las variaciones, como diciendo:
// "Sigamos, ya modifique los pixeles, esta lista la imagen"
popMatrix();
popStyle();
}
void dataZone (boolean print) {
pushMatrix();
pushStyle();
rectMode (CORNERS);
textAlign (CENTER, CENTER);
stroke(255);
colorMode(HSB);
//IMPRIMIMOS para tener certeza que nuestra lista contiene datos correctos
float vColor = 200 / zonas;
int cx=0;
int cy=0;
for ( int z=0 ; z < zonas ; z++) {
cx = z%divX;
cy = (int) z/divX;
int leftX = X1 + int (interAreaWidth * cx);
int rightX = X1 + int (interAreaWidth * (cx+1) );
int upY = Y1 + int (interAreaHeight * cy );
int bottomY = Y1 + int (interAreaHeight * (cy+1) );
fill (vColor*z, 120, 120, 200);
rect (leftX, upY, rightX, bottomY);
if (print) {
println (" pixelsRefZone"+z+": "+ pixelsRefZone[z].size() ); //imprime la cantidad de pixeles por zona
}
stroke(0);
fill (0);
textSize (15);
text ("Zona"+z+": ", leftX+(interAreaWidth/2), upY+(interAreaHeight/2)-10 );
text (pixelsRefZone[z].size(), leftX+(interAreaWidth/2), upY+(interAreaHeight/2)+10 );
}
if (print) {
println ("__________________________________");
println ("Total de zonas calculadas: "+zonas);
}
popMatrix();
popStyle();
}
void detectionZones () {
pushMatrix();
pushStyle();
rectMode (CORNERS);
cam.loadPixels(); //se llama antes de acceder al array de pixeles, diciendo "carga los pixeles, quiero acceder a ellos"
int i=0;
//For para recorrer cada una de las zonas de deteccion (recordar zonas = (divX*divY))
int cx=0;
int cy=0;
for ( int z=0 ; z < zonas ; z++) {
//Lista donde se almacenará temporalmente la posicion de los pixeles blancos de cada una
//de las zonas "z", desde 0 hasta el ultimo valor de z.
IntList listaZonaTemporal = new IntList();
//DEFINICION de variables definir los limites de cada una de las ZONAS a detectar
cx = z%divX; //la variable cx, queda en un loop entre 0 y el valor de "divX"
cy = (int) z/divX;
int leftX = X1 + int (interAreaWidth * cx); //X1 es la distancia entre el borde iz de la imagen y el pixel iz desde donde comenzamos a detectar
int rightX = X1 + int (interAreaWidth * (cx+1) );
int upY = Y1 + int (interAreaHeight * cy ); //Y1 es la distancia entre el borde superior de la imagen y el pixel sup desde donde comenzamos a detectar
int bottomY = Y1 + int (interAreaHeight * (cy+1) );
//dos BUCLES anidados, para recorrer desde la iz-arriba hasta la der-abajo todos los pixeles de cada zona
for (int x = leftX ; x < rightX; x++) {
for (int y = upY; y < bottomY; y++) {
i = x + y * cam.width; //formula que calcula la posicion del pixel segun las posiciones X e Y
int v = cam.pixels[i] & 0xFF; // "v" almacena el valor en escala de grises del pixel
//RECORDAR que la imagen que se analiza fue filtrada para obtener solo blancos y negros
// int vColor = 255 / zonas;
if (v == 255) listaZonaTemporal.append(i);//con .append agregamos la posición (i) del pixel a la lista temporal
}
}
//se almacenan los valores de "listaZonaTemporal" dentro del array de listas pixelsRefZone
//recordar: esta lista almacena la posicion de todos los pixeles blancos
pixlesCurrentZone[z] = listaZonaTemporal;
}
cam.updatePixels(); //esta funcion se llama despues de haber terminado las variaciones, como diciendo:
// "Sigamos, ya modifique los pixeles, esta lista la imagen"
popMatrix();
popStyle();
}
void zonesAnalysis (boolean see, int ua, int uc) {
int tempZonaActiva = 0 ;
int tempIndexZona =0;
int umbralActivacion = ua; //el umbral para establecer cuantos pixeles son necesarios que cambien para
//activar una Zona
int umbralCambio = uc; //el umbral para establecer cuantos pixeles son necesarios que cambien
//para establecer una nueva zona de activacion
zonaAnterior = zonaActiva;
for ( int z=0 ; z < zonas ; z++) {
int tempDif = abs ( pixelsRefZone[z].size() - pixlesCurrentZone[z].size() );
zonesVariation [z] =tempDif;
}
for ( int z=0 ; z < zonas ; z++) {
// println ("tdifBlob"+s+": "+ difBlob[s] );
if (zonesVariation[z] > tempZonaActiva) {
tempZonaActiva = zonesVariation[z];
tempIndexZona = z;
}
}
int cal = abs (tempZonaActiva - zonaAnterior);//diferencia entre la temporal zona activa y la zona anterior
//si la maxima variacion (tempZonaActiva) no es mayor que "umbralActivacion" no se toma en cuenta
//y vuelve a estado inicial
if (tempZonaActiva < umbralActivacion ) {
zonaActiva = 0;
indexZona = -1;
}
//Ahora si la diferencia entre la temporal zona activa y la zona anterior es mayor a 1000
//solo entonces se reescribe la zona activa "oficial"
else if ( cal > umbralCambio ) {
zonaActiva = tempZonaActiva;
indexZona = tempIndexZona;
}
if (see) {
println ( "zonaActiva: " + zonaActiva);
println ( "indexZona: " + indexZona);
}
}
void viewActiveZone () {
pushMatrix();
pushStyle();
rectMode (CORNERS);
textAlign (CENTER, CENTER);
int cx = indexZona%divX; //la variable cx, queda en un loop entre 0 y el valor de "divX"
int cy = indexZona/divX; //cuando cx es 0 la variable cy se suma en uno
int leftX = X1 + int (interAreaWidth * cx); //X1 es la distancia entre el borde iz de la imagen y el pixel iz desde donde comenzamos a detectar
int rightX = X1 + int (interAreaWidth * (cx+1) );
int upY = Y1 + int (interAreaHeight * cy ); //Y1 es la distancia entre el borde superior de la imagen y el pixel sup desde donde comenzamos a detectar
int bottomY = Y1 + int (interAreaHeight * (cy+1) );
fill (120,50,200, 150);
rect (leftX, upY, rightX, bottomY);
fill (0);
textSize(15);
text ("Zona Activa", leftX+(interAreaWidth/2), upY+(interAreaHeight/2)-40 );
textSize(10);
text ("variacion de: ", leftX+(interAreaWidth/2), upY+(interAreaHeight/2)+25 );
text (zonaActiva, leftX+(interAreaWidth/2), upY+(interAreaHeight/2)+38 );
popMatrix();
popStyle();
}
int getActiveZone () {
return indexZona;
}
}