Echo Lake - Even The Blind
Dead Berlin - Hipnosis
Ombre - Tormentas
Ssaliva - AVE
Will Stratton - Who Will
Jacaszek - White Wind Dance
The XX - Fiction (Kid Smpl Remix)
Black Sabbath - Planet aravan (Poolside Rework extended intro)
Monomono - Water Pass Gari (Pts 1 & 2)
Free Association - Purple Mikes
Fela Kuti - No Possible (Joystick Jays Vu Remix)
I answered some questions on the Processing forum which led to me writing this small function to determine the centroid of a polygon it uses this formula to determine the position of the centroid, Cx and Cy:


where

it might be useful for someone.
class pPoint { int x, y; pPoint(int x, int y) { this.x = x; this.y = y; } } void setup() { size(400,400); noFill(); rect(10,10,200,200); pPoint[] pArray = new pPoint[4]; pArray[0] = new pPoint(10,10); pArray[1] = new pPoint(210,10); pArray[2] = new pPoint(210,210); pArray[3] = new pPoint(10,210); pPoint pp = getCentroid(pArray); println(pp.x + "," + pp.y); ellipse(pp.x, pp.y, 2, 2); } pPoint getCentroid(pPoint[] pArray) { int X = 0; int Y = 0; int A = 0; int numPoints = pArray.length; println(numPoints); for (int i = 0; i < numPoints-1; i++ ) { X = X + (pArray[i].x + pArray[i+1].x) * (pArray[i].x*pArray[i+1].y - pArray[i+1].x*pArray[i].y); Y = Y + (pArray[i].y + pArray[i+1].y) * (pArray[i].x*pArray[i+1].y - pArray[i+1].x*pArray[i].y); A = A + ((pArray[i].x * pArray[i+1].y) - (pArray[i+1].x * pArray[i].y)); } A = A/2; X = X/(6*A); Y = Y/(6*A); pPoint pp = new pPoint(X,Y); return pp; }
imContinuing on with the image processing theme I looked at blurring an image. Gaussian Blur is similar to the Sobel edge detection algorithm insomuch that for each pixel you are processing it looks at the surrounding pixels to determine what change needs to be done. Each pixel becomes the average of the pixels around it, except that it is a weighted average, this means that the pixels closer to the centre are of more importance.
To what importance we need to give each pixel surrounding and including the centre, we need to use this equation:

Where x is horizontal distance from the centre pixel, y is the vertical distance from and sigma is the blur value (the higher the value the more the blur).
In processing the equation would look like:
weightingValue = 1/(2*PI*sigma*sigma) *
exp(-1*((x*x)+(y*y))/(2*(sigma*sigma)));
By plugging in the x,y and sigma values for each pixel we end up with 9 weighting values that I store in an array. These values need to be normalised before they can be used to change the colour values of a pixel, to do this is simple, add up all of the current weighting values and then multiply by 1/total, this ensures that the total of the new values will add up to 1.
Now you have the weighting values you can step through every pixel to determine the colour intensities of the surrounding values and then multiply them buy the weighted value which are then added together to create a new value.
Working out the top middle value and adding together would look like this:
//top middle
//get colour of top middle pixel
px = pixels[((y-1)*width)+x];
// get r,g and b values for top middle pixel and multiply by weighting
redvalue = red(px)*kernelWeightings[1];
bluevalue = blue(px)*kernelWeightings[1];
greenvalue = green(px)*kernelWeightings[1];
// add weighted r,g and b values together
redIntensity += redvalue;
greenIntensity += greenvalue;
blueIntensity += bluevalue;
Once all of the colour values of the surrounding pixels have been weighted and added together we can then plug them back into the orignal pixel, note that I have used a array of pixels to do this as we don’t want to change the original values until everyone of them has been modified.
pixelarray[x+(width*y)] = color(redIntensity,greenIntensity,blueIntensity);
After this we can use the array of pixels to create a new image.
for(int i = 0; i<width*height;i++) {
pixels[i] = pixelarray[i];
}
background(0);
updatePixels();
Passing through the pixels more than once will produce an image that looks something like this:

Full code:
float sigma = 3.5; //The blur factor float returnWeightingValue(float x, float y) { float weightingValue; //Gaussian Equation weightingValue = 1/(2*PI*sigma*sigma) * exp(-1*((x*x)+(y*y))/(2*(sigma*sigma))); return weightingValue; } void gaussBlur() { float p = returnWeightingValue(0,0); float[] kernelWeightings = new float[9]; float normVal = 0; //top left kernelWeightings[0] = returnWeightingValue(1,1); normVal+= kernelWeightings[0]; //top middle kernelWeightings[1] = returnWeightingValue(0,1); normVal+= kernelWeightings[1]; //top right kernelWeightings[2] = returnWeightingValue(1,1); normVal+= kernelWeightings[2]; //mid left kernelWeightings[3] = returnWeightingValue(1,0); normVal+= kernelWeightings[3]; //middle kernelWeightings[4] = returnWeightingValue(0,0); normVal+= kernelWeightings[4]; //mid right kernelWeightings[5] = returnWeightingValue(1,0); normVal+= kernelWeightings[5]; //bottom left kernelWeightings[6] = returnWeightingValue(1,1); normVal+= kernelWeightings[6]; //bottom middle kernelWeightings[7] = returnWeightingValue(0,1); normVal+= kernelWeightings[7]; //bottom right kernelWeightings[8] = returnWeightingValue(1,1); normVal+= kernelWeightings[8]; for (int i = 0; i<9; i++) { kernelWeightings[i] = (1/normVal)*kernelWeightings[i]; } loadPixels(); int[] pixelarray = new int[width*height]; float redvalue, bluevalue, greenvalue; float redIntensity, greenIntensity, blueIntensity; color px; for (int x = 1 ; x < width-1; x++) { for (int y = 1; y < height-1; y++) { //top left Pixel px = pixels[((y-1)*width)+(x-1)]; redvalue = red(px)*kernelWeightings[0]; bluevalue = blue(px)*kernelWeightings[0]; greenvalue = green(px)*kernelWeightings[0]; redIntensity = redvalue; greenIntensity = greenvalue; blueIntensity = bluevalue; //top middle px = pixels[((y-1)*width)+x]; redvalue = red(px)*kernelWeightings[1]; bluevalue = blue(px)*kernelWeightings[1]; greenvalue = green(px)*kernelWeightings[1]; redIntensity += redvalue; greenIntensity += greenvalue; blueIntensity += bluevalue; // top right px = pixels[((y-1)*width)+x+1]; redvalue = red(px)*kernelWeightings[2]; bluevalue = blue(px)*kernelWeightings[2]; greenvalue = green(px)*kernelWeightings[2]; redIntensity += redvalue; greenIntensity += greenvalue; blueIntensity += bluevalue; //middle left pixel px = pixels[(y*width)+(x-1)]; redvalue = red(px)*kernelWeightings[3]; bluevalue = blue(px)*kernelWeightings[3]; greenvalue = green(px)*kernelWeightings[3]; redIntensity += redvalue; greenIntensity += greenvalue; blueIntensity += bluevalue; //middle px = pixels[(y*width)+x]; redvalue = red(px)*kernelWeightings[4]; bluevalue = blue(px)*kernelWeightings[4]; greenvalue = green(px)*kernelWeightings[4]; redIntensity += redvalue; greenIntensity += greenvalue; blueIntensity += bluevalue; //middle right px = pixels[(y*width)+x+1]; redvalue = red(px)*kernelWeightings[5]; bluevalue = blue(px)*kernelWeightings[5]; greenvalue = green(px)*kernelWeightings[5]; redIntensity += redvalue; greenIntensity += greenvalue; blueIntensity += bluevalue; //bottom left px = pixels[((y+1)*width)+(x-1)]; redvalue = red(px)*kernelWeightings[6]; bluevalue = blue(px)*kernelWeightings[6]; greenvalue = green(px)*kernelWeightings[6]; redIntensity += redvalue; greenIntensity += greenvalue; blueIntensity += bluevalue; //bottom middle px = pixels[((y+1)*width)+x]; redvalue = red(px)*kernelWeightings[7]; bluevalue = blue(px)*kernelWeightings[7]; greenvalue = green(px)*kernelWeightings[7]; redIntensity += redvalue; greenIntensity += greenvalue; blueIntensity += bluevalue; //bottom right px = pixels[((y+1)*width)+x+1]; redvalue = red(px)*kernelWeightings[8]; bluevalue = blue(px)*kernelWeightings[8]; greenvalue = green(px)*kernelWeightings[8]; redIntensity += redvalue; greenIntensity += greenvalue; blueIntensity += bluevalue; pixelarray[x+(width*y)] = color(redIntensity,greenIntensity,blueIntensity); } } for(int i = 0; i<width*height;i++) { pixels[i] = pixelarray[i]; } background(0); updatePixels(); } void setup () { size(375,500); PImage img = loadImage("richard2.jpg"); image(img,0,0); } void draw() { if (mousePressed == true) { gaussBlur(); } }
Here is a quick run through of the code used to do an edge detection in Processing. First up I create an array that can contain all of the values of the screen intensities, place an image on the screen and load the image pixels into the system Pixels[] array:
int[] pixelarray = new int[width*height];
PImage img = loadImage(“image.jpg”);
image(img,0,0);
loadPixels();
Iterating through each individual pixel, I get red, green and blue intensity values for that pixel add them together and depending on the values in the Sobel operator I have multiplied and added them to the overall intensity. For example the top left pixel in the Sobel matrix:
px = pixels[((y-1)*width)+(x-1)];
redvalue = red(px);
bluevalue = blue(px);
greenvalue = green(px);
intensity = redvalue + greenvalue + bluevalue;
Gx += -intensity;
Gy += intensity;
Once I have worked out values for all of the surrounding pixels I work out using Pythagoras the overall gradient length. Then I normalise it so that it can be used as a output value.
//calculate normalised length of gradient
glength = sqrt((Gx*Gx)+(Gy*Gy));
glength = (glength/4328) * 255;
I load this new information into the array of intensities which is used to create the image of the outline. I have also used a threshold value to remove the detail from within the picture.
if (glength > 10)
pixelarray[x+(width*y)] = color(glength);
else
pixelarray[x+(width*y)] = color(0);
Finally I load the array into the system array of pixels which is used to display the new image.
for(int i = 0; i<width*height;i++) {
pixels[i] = pixelarray[i];
}
Full code - https://github.com/bigrichardc/sketchbook/blob/master/sobelImageDetection.pde
I’ve been doing some experiments with altering colour values of digital images and video depending upon their initial values, this led me to looking into how edge detection worked, doing a quick web search led me to pages about the Sobel operator. Back in the mists of time I did a mathematics degree but after many years of not using any of the hard (or even easy) maths I was taught, I have forgotten it all, and so was left scratching my head looking at the various matrices and equations and words like convolution that I came across.
After a bit more head scratching and considering putting on the too hard to do file, I found this Python/C++ tutorial on the which allowed me to work out what was going on and realise that the maths stuff just looked scary.
In basic terms the Sobel operator is used to determine the intensity of colour of a pixel and of it’s neighbours then using a method called convolution approximates the difference in intensity along the x and y axis. A bit of a mouthfull I know but basically it does this:
As seen in my bad diagram.

If you do this for each pixel on the screen you will get an intensity change level for each will allow you to build a picture showing the outlines like so:
Another thing you need to know is that the Sobel operator consists of two matrices that look like this:

Basically these are the values you multiply the intensity of each pixel surrounding the pixel you are working out the change in intensity for, going left to right (Gx) and from top to bottom (Gy). So when working out the change across the x-axis the position in the matrix corresponds to the value you would multiply the intensity of the pixel by, for example the pixel intensity in the top left hand corner by -1 and the intensity of the bottom right by +1.
That really is all you need to know in order to be able to detect edges in an image, there are other types of operators that can be used to determine edges each with their own properties but as yet I have not looked at them.
For more formal information including scary looking maths here’s the Sobel operator Wiki page - http://en.wikipedia.org/wiki/Sobel_operator
If that is not making too much sense my next post will look at the code I used to produce the above image which hopefully makes things clearer.
Experimenting a bit further with matrix co-ordinates, I realised that its quite easy to forget which order that you are supposed perform the order of things, so I (badly) drew an easy to follow diagram that shows me how to do it.

This sketch uses the translate, rotate and push and pop matrix functions to rotate rectangles held in an ArrayList as the mouse hovers over them.
class Square { int x, y; int sideLength = 50; int pen = 1; int r = 120; Square() { x = (int)random(width-sideLength); y = (int)random(height-sideLength); } Square(int x1, int y1) { x=x1; y=y1; } void drawSquare() { strokeWeight(pen); fill(r,0,0); pushMatrix(); translate(x,y); rect(0,0,sideLength, sideLength); line(-sideLength/2,-sideLength/2,sideLength/2,sideLength/2); popMatrix(); } void drawRotatedSquare() { strokeWeight(pen); fill(r,255-r,r); pushMatrix(); translate(x,y); rotate(90*PI/180); rect(0,0,sideLength, sideLength); line(-sideLength/2,-sideLength/2,sideLength/2,sideLength/2); popMatrix(); } boolean mouseOver(int mx,int my) { if ( mx >= x-sideLength/2 && mx < x+sideLength/2) { if ( my >= y-sideLength/2 && my < y+sideLength/2) { return true; } else return false; } else return false; } } Square sq; ArrayList sqs = new ArrayList(); int rotCount = 0; void setup() { rectMode(CENTER); size(500,500); for (int y = 0; y<height-50; y+=100) { for (int x = 0; x < width-50; x+=100) { sq = new Square(x+50,y+50); sqs.add(sq); } } } void draw() { rotCount = 0; background(190,0,0); int listSize = (sqs.size()); Square s; for (int i = 0; i<listSize; i++) { s = (Square)sqs.get(i); if (s.mouseOver(mouseX,mouseY)) { s.pen = 6; s.r = (int)random(255); s.drawRotatedSquare(); } else { s.pen = 1; s.drawSquare(); } } }
Being a bit lazy it’s taken me quite a while to work out how pushMatrix() and popMatrix() actually work and why I would need them. Whenever I have tried to rotate things around point before they’ve just gone whizzing off around the screen and in no apparent order whatsoever so I went off in a huff and did something else instead. Today I decided to sit down and actually see where I was going wrong.
With the help of these three helpful pages:
1. Daniel Shiffman’s Learning Processing
2. Tlll Nagel’s Creative Coding
3. Critical Zero
The rotate() function in Processing rotates the entire co-ordinate matrix which means that everything rotates around the same centre point. A co-ordination matrix is like a glass surface with images drawn onto it which can then me moved around or rotated. Calling the pushMatrix() function adds another co-ordinate matrix which would be similar to placing another glass surface over the original, this can also be moved and rotated and drawn on without effecting the original. The popMatrix() function then returns you to the previous matrix and allows you to work on that.
This is a simple sketch that fills the screen with rectangles and using pushing and popping rotates each of them around their centre points:
float angle = 0;
void setup () {
size(500,500);
rectMode(CENTER);
}
void draw() {
background(0);
angle+= 0.05;
for (int y = 0; y < height-50; y+=50)
{
for (int x = 0; x < width-50; x+=50)
{
pushMatrix();
translate(50+x,50+y);
rotate(angle);
rect(0,0,50,50);
popMatrix();
}
}
}