week 5 ++ pixel neighbors
|
solving the edge problem ( code) :
so I was initially trying this with a complicated set of extra variables
(I think I often do this because I like to have the freedom of doing dynamic stuff with a set of variables)
but the min/max idea was pretty elegant so I stuck with that.
this example uses a basic gaussian blur
|
/* in the setup() */
for (int i = 0; i < imageW - 0; i++){
for (int j = 0; j < imageH - 0; j++){
// drawing inside the lines...
int nw = pixelsA[MAX(j - 1, 0 ) * imageW + MAX(i - 1, 0 )];
int n_ = pixelsA[MAX(j - 1, 0 ) * imageW + (i )];
int ne = pixelsA[MAX(j - 1, 0 ) * imageW + MIN(i + 1, imageW - 1)];
int w_ = pixelsA[(j ) * imageW + MAX(i - 1, 0 )];
int me = pixelsA[(j ) * imageW + (i )];
int e_ = pixelsA[(j ) * imageW + MIN(i + 1, imageW - 1)];
int sw = pixelsA[MIN(j + 1, imageH - 1) * imageW + MAX(i - 1, 0 )];
int s_ = pixelsA[MIN(j + 1, imageH - 1) * imageW + (i )];
int se = pixelsA[MIN(j + 1, imageH - 1) * imageW + MIN(i + 1, imageW - 1)];
float newVal = (nw * kernel[0] + n_ * kernel[1] + ne * kernel[2] +
w_ * kernel[3] + me * kernel[4] + e_ * kernel[5] +
sw * kernel[6] + s_ * kernel[7] + se * kernel[8]) / kernelWeight;
newVal = MIN(MAX(newVal, 0), 255);
pixelsB[(j ) * imageW + (i )] = newVal;
}
}
|
|
edge detection cases ( code) :
playing around with different edge detection with compounded kernels (4-direction and 8-direction).
so the first set of images shows that the 8-direction edge detection (right) actually doesn't work as well as the 4-direction one (center),
because the edges are restricted to certain directions, so looking at all directions averages out the important edges.
the second set of images shows that 8-direction (right) works best with images of edges in all or many directions.

|
/* in the setup() */
/* this is the main chunk of code */
float newVals[8];
// -- 4x kernel averaging --
float finalVal_4 = 0;
for (int nv = 0; nv < 2; nv++){
newVals[nv] = (nw * kernels[nv][0] + n_ * kernels[nv][1] + ne * kernels[nv][2] +
w_ * kernels[nv][3] + me * kernels[nv][4] + e_ * kernels[nv][5] +
sw * kernels[nv][6] + s_ * kernels[nv][7] + se * kernels[nv][8]) / kernelWeight;
newVals[nv] = MIN(MAX(newVals[nv], 0), 255);
finalVal_4 += newVals[nv];
}
finalVal_4 = finalVal_4/2;
pixelsB[j * imageW + i] = finalVal_4;
// -- 8-directional kernel averaging --
float finalVal_8 = 0;
for (int nv = 0; nv < 8; nv++){
newVals[nv] = (nw * kernels[nv][0] + n_ * kernels[nv][1] + ne * kernels[nv][2] +
w_ * kernels[nv][3] + me * kernels[nv][4] + e_ * kernels[nv][5] +
sw * kernels[nv][6] + s_ * kernels[nv][7] + se * kernels[nv][8]) / kernelWeight;
newVals[nv] = MIN(MAX(newVals[nv], 0), 255);
finalVal_8 += newVals[nv];
}
finalVal_8 = finalVal_8/8;
pixelsC[j * imageW + i] = finalVal_8;
|
|
advanced drawing tool ( code) :
so here I've got it loading an image, and doing adding ome drawing mechanism (noisy, cyclic grayscale brush).
seems like a pretty intense drawing tool (intense on memory), but could definitely come up with some nice real-time effects

|
for (int i = 0; i < imageW - 0; i++){
for (int j = 0; j < imageH - 0; j++){
// drawing inside the lines...
int nw = pixelsC[MAX(j - 1, 0 ) * imageW + MAX(i - 1, 0 )];
int n_ = pixelsC[MAX(j - 1, 0 ) * imageW + (i )];
int ne = pixelsC[MAX(j - 1, 0 ) * imageW + MIN(i + 1, imageW - 1)];
int w_ = pixelsC[(j ) * imageW + MAX(i - 1, 0 )];
int me = pixelsC[(j ) * imageW + (i )];
int e_ = pixelsC[(j ) * imageW + MIN(i + 1, imageW - 1)];
int sw = pixelsC[MIN(j + 1, imageH - 1) * imageW + MAX(i - 1, 0 )];
int s_ = pixelsC[MIN(j + 1, imageH - 1) * imageW + (i )];
int se = pixelsC[MIN(j + 1, imageH - 1) * imageW + MIN(i + 1, imageW - 1)];
// -- 4x kernel averaging --
float newVals[8];
float finalVal = 0;
for (int nv = 3; nv < 4; nv++){
newVals[nv] = (nw * kernels[nv][0] + n_ * kernels[nv][1] + ne * kernels[nv][2] +
w_ * kernels[nv][3] + me * kernels[nv][4] + e_ * kernels[nv][5] +
sw * kernels[nv][6] + s_ * kernels[nv][7] + se * kernels[nv][8]) / kernelWeight;
newVals[nv] = MIN(MAX(newVals[nv], 0), 255);
finalVal += newVals[nv];
}
/* -- drawing -- */
float diffx = (mouseX - i);
float diffy = (mouseY - j);
float ran = ofRandomuf();
float dist = sqrt(diffx*diffx + diffy*diffy) + 80*ran;
//float ran = ofRandomuf();
//float ran2 = ofRandomuf();
float dist_var = 60;
float draw = 128 * (1 + sin(float(time) / 30));
if (dist < dist_var){
finalVal = MIN(MAX(draw, 0), 255);
}
/*else {
//finalVal = ;
}*/
pixelsB[j * imageW + i] = finalVal;
}
}
|
|
conway's life ( code) :
standard recreation of conway's life. I used a random noise generator to populate at first.
Also, there are two scrolling histograms plotting the total 'live' cells and the total moving cells (went from black to white).
I tried playing around with the automata rules and sure enough slight variations produce pretty uninteresting stuff.

|
time++;
if(time == 1000){
time = 0;
}
int total_moved = 0;
int total_live = 0;
for (int n = 0; n < imageW*imageH; n++){
pixelsC[n] = pixelsB[n];
}
for (int i = 0; i < imageW - 0; i++){
for (int j = 0; j < imageH - 0; j++){
// drawing inside the lines...
int dir[8];
dir[0] = pixelsC[MAX(j - 1, 0 ) * imageW + MAX(i - 1, 0 )];
dir[1] = pixelsC[MAX(j - 1, 0 ) * imageW + (i )];
dir[2] = pixelsC[MAX(j - 1, 0 ) * imageW + MIN(i + 1, imageW - 1)];
dir[3] = pixelsC[(j ) * imageW + MAX(i - 1, 0 )];
int me = pixelsC[(j ) * imageW + (i )];
dir[4] = pixelsC[(j ) * imageW + MIN(i + 1, imageW - 1)];
dir[5] = pixelsC[MIN(j + 1, imageH - 1) * imageW + MAX(i - 1, 0 )];
dir[6] = pixelsC[MIN(j + 1, imageH - 1) * imageW + (i )];
dir[7] = pixelsC[MIN(j + 1, imageH - 1) * imageW + MIN(i + 1, imageW - 1)];
// count number of neighboring live cells
int live = 0;
for (int d = 0; d < 8; d++){
if(dir[d] == 255){
live++;
}
}
// decide who lives and who dies
if(me == 0 && live == 3){
me = 255; // frankencell, come to life!!!
}else if(me == 255 && (live == 3 || live == 2)){
me = 255; // stay alive no matter what it takes...
}else{
me = 0; // squished or lonely
}
// count moving cells
if(me == 255 && pixelsB[j * imageW + i] == 0){
total_moved++;
}
pixelsB[j * imageW + i] = me;
}
}
// count TOTAL number of neighboring live cells
for(int n = 0; n < imageH*imageW; n++){
if(pixelsB[n] == 255){
total_live++;
}
}
living[time] = total_live;
moving[time] = total_moved;
|
|