We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexDiscussionExhibition › Voronoi Portraits
Page Index Toggle Pages: 1
Voronoi Portraits (Read 2429 times)
Voronoi Portraits
Apr 24th, 2010, 9:57pm
 
Here is a series of portraits I created using Voronoi diagrams:
http://www.flickr.com/photos/36321226@N04/sets/72157623922421898/

I used the mesh library by Lee Byron for generating the diagrams themselves - http://www.leebyron.com/else/mesh/

Guy

Vornonoi Portraits
Reply #1 - Apr 25th, 2010, 12:29am
 
It looks real nice, Guy. Did you make these on the fly (live cam) or by importing a photo that was allready made?

Any chance on posting an example code?


Re: Voronoi Portraits
Reply #2 - Apr 25th, 2010, 10:23pm
 
Thanks - the images were already made.

attached is the code. you need to pick the values of brightness that you want to generate points from (upper and lower) - and the number of points you want to skip (lowSkip and highSkip). Then press go and generate the image.



Code:
import megamu.mesh.*;
import controlP5.*;

float upperBright = 200;
float lowerBright=150;
float lowSkip = 1;
float highSkip = 7;


PointList points = new PointList();
PImage img;
Voronoi voronoi;
ControlP5 controlP5;
boolean ready = false;

void setup() {
size(600,600);
frameRate(10);
//noCursor();
img = loadImage("portrait2.jpg");
controlP5 = new ControlP5(this);
ControlWindow controlWindow;
controlWindow = controlP5.addControlWindow("controlP5window",100,100,400,200);
controlWindow.hideCoordinates();
Controller np = controlP5.addSlider("upper",0,255,upperBright,40,40,100,10);
np.setWindow(controlWindow);
Controller ns = controlP5.addSlider("lower",0,255,lowerBright,40,60,100,10);
ns.setWindow(controlWindow);
Controller ls = controlP5.addSlider("lowskip",1,20,lowSkip,40,80,100,10);
ls.setWindow(controlWindow);
Controller hs = controlP5.addSlider("highskip",1,20,highSkip,40,100,100,10);
hs.setWindow(controlWindow);
Controller go = controlP5.addButton("go",1, 40,120, 50, 20);
go.setWindow(controlWindow);

println("done setup");
}

void upper(float value) {
upperBright = int(value);
}

void lower(float value) {
lowerBright = int(value);
}

void lowskip(float value) {
lowSkip = value;
}

void highskip(float value) {
highSkip = value;
}

void go() {
ready = false;
points.clear();
getAllPoints();
voronoi = new Voronoi( points.toArray());
ready = true;
}

void draw() {
background(0);
stroke(128);
if (!ready) {
return;
}
MPolygon[] regions = voronoi.getRegions();
stroke(128);
fill(0);
for(int i=0; i<regions.length; i++) {
float[][] regionCoordinates = regions[i].getCoords();
regions[i].draw(this);
}

float[][] edges = voronoi.getEdges();
for(int i=0; i<edges.length; i++) {
float startX = edges[i][0];
float startY = edges[i][1];
float endX = edges[i][2];
float endY = edges[i][3];
line( startX, startY, endX, endY );
}
fill(128);
noStroke();
if(mousePressed){
tint(255,100);
image(img,0,0);
}


}

void mousePressed() {
float b = brightness(img.get(mouseX, mouseY));
println(b);
}
void keyPressed() {
if (key == 's')
saveFrame();
}



void getAllPoints() {
for (int x = 0; x < width; x+=int(random(lowSkip,highSkip))) {
for (int y = 0; y < height; y+=int(random(lowSkip,highSkip))) {
float b = brightness(img.get(x,y));
if (b <= upperBright && b >= lowerBright) {
points.addPoint(new Point(x,y));
}
}
}
println("total:"+points.size());
}

class PointList {
ArrayList points = new ArrayList();

public void addPoint(float x, float y) {
addPoint(new Point(x,y));
}

public void addPoint(Point p) {
points.add(p);
}

public boolean isEmpty() {
return points.isEmpty();
}

float[][] toArray() {
float[][] arr = new float[points.size()][2];
for (int i = 0; i < points.size(); i++) {
Point p = (Point) points.get(i);
arr[i][0] = p.getX();
arr[i][1] = p.getY();
}
return arr;
}

int size() {
return points.size();
}

Point get(int i) {
return (Point) points.get(i);
}

void clear() {
points.clear();
}
}

class Point {
float x,y;

public Point(float x_, float y_) {
x = x_;
y = y_;
}

float getX() {
return x;
}
float getY() {
return y;
}

}


Re: Voronoi Portraits
Reply #3 - Apr 27th, 2010, 11:45am
 
I had been toying with idea of creating some voronoi portraits myself, well done for publishing your code. I was inspired to see whether I could port the application to ruby-processing. Now controlP5 uses reflection and that won't work with ruby-processing, but fortunately ruby processing has a control_panel library that actually makes setting up the gui even easier, to view the results check out my blog http://learning-ruby-processing.blogspot.com/2010/04/using-voronoi-library-in-ru....
There are few ways in which my code deviate from yours, but once again thanks for the inspiration (and thanks to Lee Byron for the library) Cool.
Re: Voronoi Portraits
Reply #4 - Apr 28th, 2010, 5:39am
 
nice work. i guess i should start learning ruby Smiley
Page Index Toggle Pages: 1