|
Author |
Topic: idiot wants to do simple error diffusion dither (Read 470 times) |
|
ndrumac Guest
|
idiot wants to do simple error diffusion dither
« on: Jan 15th, 2004, 8:43am » |
|
you guys probably get the "idiot who can't program what's wrong with my program help me" a lot - but proce55ing seems to be somewhat catering to artists and non-mathematical types so i figured someone would be sympathetic i'm just trying to write an implementation of the floyd-steinberg error diffusion dither to apply on top of 3d animations and whatnot - and i can't figure it out too well. I think my problem has to do with the fact that i used a crude array to store the error-dividends per pixel, and i can't tell if it's a grammatical error or something more fundamental - i'm new to all of this. so should i bother posting my code, or is this an interesting enough problem for one of the smart guys to write it in 20 minutes? I love what you're doing here -andrew p.s: sidenote i posted a while back about copying program feedback to use elsewhere and someone suggested that I use "println" and then copy it out of the console- but that was what I was talking about, I'm running proce55ing on os 10.2.6 on an ibook, and whatever i try to copy out of the console just doesn't write to clipboard. probably i should make a separate post in the proper section but it's late thanks again
|
|
|
|
TomC
|
Re: idiot wants to do simple error diffusion dithe
« Reply #1 on: Jan 15th, 2004, 3:13pm » |
|
If you post your code, then it's likely that a 20 minute smart-guy job becomes a 2 minute bug hunt. Posting code is good, if you're not precious about it. On windows, the lib folder contains two text files (stdout.txt and stderr.txt) - there might be a mac equivalent?
|
|
|
|
elout
|
Re: idiot wants to do simple error diffusion dithe
« Reply #2 on: Jan 15th, 2004, 3:24pm » |
|
This a random black/white dither routine. (! not the floyd-steinberg routine) Code: // elout de kok 2003 - p67 // http://www.xs4all.nl/~elout/ //------mouse & stuff int mx,my,sx=140,sy=120, midx,midy; float zangle; // use a precalculated random int buffer // faster then calculating random() float`s all the time int my_randombuffersize=5000; int [] my_randombuffer=new int[my_randombuffersize]; int my_randomstep=1; int my_randomposition=0; void setup() { size(400,400); midx=width/2; midy=height/2; // fill the precalculated random buffer with random-numbers for(int i=0; i<my_randombuffersize; i++) { my_randombuffer[i]=(int)random(256); } } void loop() { //clear screen background(220,220,220); // set the position to the middle of your screen translate(midx, midy, 0); //check mouse for rotation mx=mouseX; my=mouseY; if ( mx > midx){sx=0-((midx-mx)/2);} else{sx=((mx-midx)/2);} if ( my > midy){sy=0-((midy-my)/2);} else{sy=((my-midy)/2);} zangle= zangle+(sx/4000.0f); rotateX(0.6+(sy/40.0)); rotateY(0.6+(sx/40.0)); rotateZ(zangle); //draw the cube stroke(250,250,250); fill(50,50,50,80); box(180.0f); //random dither the image to black and white for (int i=0,r0,col;i<width*height ;i++) { col=get_my_random();//(int) random(255); r0=(((pixels[i] >> 16) & 0xff) + col)/2; //just get the red value. if (r0>155){r0=255;} else {r0=0;} pixels[i] = ((0xff<<24) | (r0<<16) | (r0<<8) | r0); } //just add a little delay so the system can handle other tasks as well delay(15); } private int get_my_random() { my_randomposition=my_randomposition+my_randomstep; if (my_randomposition>=my_randombuffersize) { my_randomstep=(int) random(20)+1; my_randomposition=(int) random(20); } return (my_randombuffer[my_randomposition]); } |
|
|
|
|
|
TomC
|
Re: idiot wants to do simple error diffusion dithe
« Reply #3 on: Jan 15th, 2004, 4:43pm » |
|
OK, I had a spare minute or two^Henty, so I had a go. There's a few too many casts/rounds/etc in there for my liking, so I'll try and tidy it up tomorrow. Code: void draw() { // draw something here for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { //int i = 255 * (int)ceil(brightness(get(x,y))/255.0f); // not sure this is right, especially int i = (int)(255.0f*round(brightness(get(x,y))/255.0f)); // changed on update - maybe better? float e = brightness(get(x,y)) - (float)i; set(x,y,grey(i)); set(x,y+1,grey(brightness(get(x,y+1))+(7.0f*e/16.0f))); set(x+1,y-1,grey(brightness(get(x+1,y-1))+(3.0f*e/16.0f))); set(x+1,y,grey(brightness(get(x+1,y))+(5.0f*e/16.0f))); set(x+1,y+1,grey(brightness(get(x+1,y+1))+(1.0f*e/16.0f))); } } } int grey(int i) { int c = color(i,i,i); return c; } int grey(float i) { return grey((int)round(i)); } |
| PS This was helpful, http://www.cs.princeton.edu/courses/archive/fall99/cs426/lectures/dither /sld021.htm the constants are on the previous slide.
|
« Last Edit: Jan 15th, 2004, 4:54pm by TomC » |
|
|
|
|
ndrumac Guest
|
Re: idiot wants to do simple error diffusion dithe
« Reply #4 on: Jan 15th, 2004, 9:54pm » |
|
fantastic - yeah, my problem was a slight numerical disparity between the actual pixel grey values and the crude huge data array to store the error values. - i appreciate the help very much! andrew
|
|
|
|
TomC
|
Re: idiot wants to do simple error diffusion dithe
« Reply #5 on: Jan 15th, 2004, 10:40pm » |
|
Glad to hear you got it sorted out. Here's one I looked up in a book. (A good book, recommended, lots of java source code that should be easy to port to processing). http://www.comp.leeds.ac.uk/nde/book/index.html Code: int threshold = 128; color black = #000000; color white = #ffffff; void setup() { size(200, 200); lights(); noStroke(); } void loop() { background(#dddddd); fill(#9080b0); // adapted from Primitives 3D by REAS <http://www.groupc.net> push(); translate(mouseX, height/2.6, 0); rotateY(0.75); box(50); pop(); push(); translate(200, height/2, -mouseY); sphere(100); pop(); if (!mousePressed) { errorDiffuseDither(); } } // implementation of algorithm 5.1 from Digital Image Processing by Nick Efford void errorDiffuseDither() { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float value = brightness(get(x,y)); float error = 0.0f; if (value < threshold) { set(x,y,black); error = value; } else { set(x,y,white); error = value - 255.0f; } set(x+1, y, grey(brightness(get(x+1, y)) + (error*7.0f/16.0f))); set(x-1, y+1, grey(brightness(get(x-1, y+1)) + (error*3.0f/16.0f))); set(x, y+1, grey(brightness(get(x, y+1)) + (error*5.0f/16.0f))); set(x+1, y+1, grey(brightness(get(x+1, y+1)) + (error*1.0f/16.0f))); } } } int grey(float i) { return grey((int)round(i)); } int grey(int i) { return color(i,i,i); } |
|
|
|
|
|
toxi
|
Re: idiot wants to do simple error diffusion dithe
« Reply #6 on: Jan 16th, 2004, 7:48pm » |
|
hey these are all really looking great! been ages since i dealt with floyd-steinberg last. i remember using it to optimize prints of the atari the 7-needle printer... sorry for re-posting old stuff, here's the link again to a perlin noise based dither: http://www.toxi.co.uk/p5/perlin/dither/ click left mouse button to see the realtime dithered version...
|
http://toxi.co.uk/
|
|
|
|