|
|
ec0d7e |
|
|
|
ec0d7e |
#include <math.h></math.h>
|
|
|
ec0d7e |
#include <stdio.h></stdio.h>
|
|
|
ec0d7e |
#include <stdlib.h></stdlib.h>
|
|
|
ec0d7e |
|
|
|
ec0d7e |
#include <helianthus.h></helianthus.h>
|
|
|
ec0d7e |
|
|
|
ec0d7e |
#include "nnlayer.inc.c"
|
|
|
ec0d7e |
|
|
|
ec0d7e |
|
|
|
ec0d7e |
NeuralLayer *nl;
|
|
|
ec0d7e |
Framebuffer fb, fbMin;
|
|
|
ec0d7e |
Animation fbAnim, fbMinAnim;
|
|
|
ec0d7e |
|
|
|
ec0d7e |
int wasPressed;
|
|
|
ec0d7e |
double prevX, prevY;
|
|
|
ec0d7e |
|
|
|
ec0d7e |
|
|
|
ec0d7e |
|
|
|
ec0d7e |
void prepareImage() {
|
|
|
ec0d7e |
int w, h;
|
|
|
ec0d7e |
unsigned char *pixels = NULL;
|
|
|
ec0d7e |
|
|
|
ec0d7e |
saveState();
|
|
|
ec0d7e |
target(fb);
|
|
|
ec0d7e |
imageFromViewport(&w, &h, &pixels);
|
|
|
ec0d7e |
restoreState();
|
|
|
ec0d7e |
if (!pixels) return;
|
|
|
ec0d7e |
|
|
|
ec0d7e |
int x0 = w, y0 = h, x1 = 0, y1 = 0;
|
|
|
ec0d7e |
for(int y = 0; y < h; ++y) {
|
|
|
ec0d7e |
for(int x = 0; x < w; ++x) {
|
|
|
ec0d7e |
if (imageGetPixel(w, h, pixels, x, y) != 0x000000ff) {
|
|
|
ec0d7e |
if (x0 > x) x0 = x;
|
|
|
ec0d7e |
if (x1 < x) x1 = x;
|
|
|
ec0d7e |
if (y0 > y) y0 = y;
|
|
|
ec0d7e |
if (y1 < y) y1 = y;
|
|
|
ec0d7e |
}
|
|
|
ec0d7e |
}
|
|
|
ec0d7e |
}
|
|
|
ec0d7e |
free(pixels);
|
|
|
ec0d7e |
pixels = NULL;
|
|
|
ec0d7e |
|
|
|
ec0d7e |
if (x1 < x0 || y1 < y0) return;
|
|
|
ec0d7e |
|
|
|
ec0d7e |
double wx = x1 - x0 + 1;
|
|
|
ec0d7e |
double wy = y1 - y0 + 1;
|
|
|
ec0d7e |
double s = 20.0/(wx > wy ? wx : wy);
|
|
|
ec0d7e |
double cx = (x0 + x1)/2.0;
|
|
|
ec0d7e |
double cy = (y0 + y1)/2.0;
|
|
|
ec0d7e |
|
|
|
ec0d7e |
double xx = 14 - s*cx;
|
|
|
ec0d7e |
double yy = 14 - s*cy;
|
|
|
ec0d7e |
double ww = s*w;
|
|
|
ec0d7e |
double hh = s*h;
|
|
|
ec0d7e |
|
|
|
ec0d7e |
saveState();
|
|
|
ec0d7e |
target(fbMin);
|
|
|
ec0d7e |
noStroke();
|
|
|
ec0d7e |
rectTextured(fbAnim, xx, yy, ww, hh);
|
|
|
ec0d7e |
imageFromViewport(&w, &h, &pixels);
|
|
|
ec0d7e |
restoreState();
|
|
|
ec0d7e |
|
|
|
ec0d7e |
if (!pixels) return;
|
|
|
ec0d7e |
double *p = nl->a;
|
|
|
ec0d7e |
for(int y = 0; y < h; ++y)
|
|
|
ec0d7e |
for(int x = 0; x < w; ++x)
|
|
|
ec0d7e |
*p++ = colorGetValue(imageGetPixel(w, h, pixels, x, y));
|
|
|
ec0d7e |
}
|
|
|
ec0d7e |
|
|
|
ec0d7e |
|
|
|
ec0d7e |
void init() {
|
|
|
ec0d7e |
background(COLOR_BLACK);
|
|
|
ec0d7e |
stroke(COLOR_WHITE);
|
|
|
ec0d7e |
fb = createFramebufferEx(512, 512, NULL, FALSE, FALSE, TRUE);
|
|
|
ec0d7e |
fbMin = createFramebufferEx(28, 28, NULL, FALSE, FALSE, TRUE);
|
|
|
ec0d7e |
fbAnim = createAnimationFromFramebuffer(fb);
|
|
|
ec0d7e |
fbMinAnim = createAnimationFromFramebuffer(fbMin);
|
|
|
ec0d7e |
|
|
|
ec0d7e |
saveState();
|
|
|
ec0d7e |
target(fb);
|
|
|
ec0d7e |
clear();
|
|
|
ec0d7e |
target(fbMin);
|
|
|
ec0d7e |
clear();
|
|
|
ec0d7e |
restoreState();
|
|
|
ec0d7e |
|
|
|
ec0d7e |
nl = nlNew(NULL, 784, 0);
|
|
|
ec0d7e |
nlNew(nl, 256, 0);
|
|
|
ec0d7e |
nlNew(nl, 128, 0);
|
|
|
ec0d7e |
nlNew(nl, 64, 0);
|
|
|
ec0d7e |
nlNew(nl, 64, 0);
|
|
|
ec0d7e |
nlNew(nl, 10, 0);
|
|
|
ec0d7e |
nlLoad(nl, "data/weights.bin");
|
|
|
ec0d7e |
}
|
|
|
ec0d7e |
|
|
|
ec0d7e |
|
|
|
ec0d7e |
void draw() {
|
|
|
ec0d7e |
saveState();
|
|
|
ec0d7e |
|
|
|
ec0d7e |
if (mouseDown("left")) {
|
|
|
ec0d7e |
double x = mouseX(), y = mouseY();
|
|
|
ec0d7e |
if (!wasPressed) prevX = x, prevY = y;
|
|
|
ec0d7e |
|
|
|
ec0d7e |
saveState();
|
|
|
ec0d7e |
strokeWidth(32);
|
|
|
ec0d7e |
target(fb);
|
|
|
ec0d7e |
line(prevX, prevY, x, y);
|
|
|
ec0d7e |
restoreState();
|
|
|
ec0d7e |
|
|
|
ec0d7e |
prevX = x, prevY = y;
|
|
|
ec0d7e |
wasPressed = TRUE;
|
|
|
ec0d7e |
} else {
|
|
|
ec0d7e |
wasPressed = FALSE;
|
|
|
ec0d7e |
}
|
|
|
ec0d7e |
|
|
|
ec0d7e |
if (keyWentDown("space")) {
|
|
|
ec0d7e |
prepareImage();
|
|
|
ec0d7e |
nlPass(nl);
|
|
|
ec0d7e |
saveState();
|
|
|
ec0d7e |
target(fb);
|
|
|
ec0d7e |
clear();
|
|
|
ec0d7e |
restoreState();
|
|
|
ec0d7e |
}
|
|
|
ec0d7e |
|
|
|
ec0d7e |
noStroke();
|
|
|
ec0d7e |
rectTextured(fbAnim, 0, 0, 512, 512);
|
|
|
ec0d7e |
|
|
|
ec0d7e |
stroke(COLOR_WHITE);
|
|
|
ec0d7e |
rectTextured(fbMinAnim, 16, 16, 28, 28);
|
|
|
ec0d7e |
|
|
|
ec0d7e |
noFill();
|
|
|
ec0d7e |
|
|
|
ec0d7e |
NeuralLayer *nlb = nlBack(nl);
|
|
|
ec0d7e |
textSize(8);
|
|
|
ec0d7e |
int res = 0;
|
|
|
ec0d7e |
for(int i = 0; i < 10; ++i) {
|
|
|
ec0d7e |
if (nlb->a[i] > nlb->a[res]) res = i;
|
|
|
ec0d7e |
textf(16, 90+8*i, "%d: %lf", i, nlb->a[i]);
|
|
|
ec0d7e |
}
|
|
|
ec0d7e |
textSize(16);
|
|
|
ec0d7e |
textf(16, 60, "%d", res);
|
|
|
ec0d7e |
|
|
|
ec0d7e |
restoreState();
|
|
|
ec0d7e |
}
|
|
|
ec0d7e |
|
|
|
ec0d7e |
|
|
|
ec0d7e |
int main(int largc, char **largv) {
|
|
|
ec0d7e |
windowSetVariableFrameRate();
|
|
|
ec0d7e |
windowSetInit(&init);
|
|
|
ec0d7e |
windowSetDraw(&draw);
|
|
|
ec0d7e |
windowRun();
|
|
|
ec0d7e |
return 0;
|
|
|
ec0d7e |
}
|
|
|
ec0d7e |
|