|
Author |
Topic: color proportions (Read 650 times) |
|
dek
|
color proportions
« on: Jun 10th, 2004, 10:50am » |
|
hey all, this is my first post and i allready have two problems for you guys to solve. problem.1 i have a bitmap picture and want to generate a list of the color proportions e.g. know that the picture is built with 2.37 % rgb(120, 200, 173), 1.71% rgb(15, 34, 177) and so on. i guess the first task is to generate a list of all the pixels and their rgb/hsb-values contained in the bitmap, then sort that list to get all the color proportions. may it be, that the 'image : extrusion' example from the 'learning' pages may lead me toward the right solution? problem.2 i'm quite new to proce55ing. i got the basics, but i guess everything i should know to solve problem.1 i'm lacking (arrays?). has anyone given any thought on this subject? i'd truly appreciate any input. thx, greg
|
|
|
|
Markavian
|
Re: color proportions
« Reply #1 on: Jun 10th, 2004, 2:56pm » |
|
Hi dek, Code: // Colour Proportions // Read image in, calculate percentage of Red, Green and Blue // Display as traced output float total_red = 0; float total_blue = 0; float total_green = 0; BImage b; b = loadImage("stripes.gif"); size(b.height, b.width); image(b, 0, 0); for(int i=0; i<b.height*b.width; i++) { color c = b.pixels[i]; total_red += red(c); total_blue += blue(c); total_green += green(c); } float total_colour = total_red + total_blue + total_green; print("Percentage Red: "+total_red/total_colour*100+" %\n"); print("Percentage Blue: "+total_blue/total_colour*100+" %\n"); print("Percentage Green: "+total_green/total_colour*100+" %\n"); |
| Heres a simplish way of getting towards what you wanted. It adds up the total amount of red/green/blue, and then divides by the total amount of colour... I'm sure with a bit of work you could modify it to list individual colours. Whats your problems with Arrays? All the information on them is in the Reference manual. Regards, - Markavian
|
|
|
|
dek
|
try, try ,try
« Reply #2 on: Jun 10th, 2004, 4:20pm » |
|
yo Markavian, your code looks like it will help me further, thx. my problem with arrays is basically that i haven't used them up to now. the reference manual tells me all i have to know, now i just have to hang in there, experiment, and develop an arrayian way of thinking. the problem there is that i haven't really got a lot of time to spare, since it's the end of semester and projects have to be finished, documentations written and presentations prepared. and none of my teachers can or wants to help me with problems regarding p5. but hey, nobody said it was gonna be easy. thanks again, Greg
|
|
|
|
dek
|
Re: color proportions
« Reply #3 on: Jun 11th, 2004, 3:39pm » |
|
hey again, i used Markavians script and have extensively messed with it. now i have a script which calculates the percentage of a certain color value in an image IF i tell the script which colors are contained in the image (it's a 16-color gif, so thats easy enough). what i want now is a script that first traces down all the different colors and saves them into an array for further processing. i came up with like following, but it doesn't really work: code: // this script (should) work for a gif-image containing 16 colors, just for testing // i don't know yet how many different colors it could manage without the CPU going bananas float[] amount = new float[16]; color[] colors = new color[16]; // "empty" colors[] for(int i=0; i<16; i++) { colors[i] = 0; } BImage b; b = loadImage("lava16colors.gif"); size(b.width, b.height); image(b, 0, 0); // trace all different colors, this part's the buggy one for(int i=0; i<b.height*b.width; i++) { for(int u=0; u<16; u++) { if(colors[u] == 0) { for(int w=0; w<16; w++) { if (colors[w] != b.pixels[i]) { colors[u] = b.pixels[i]; } } } } } // calculate amount for(int i=0; i<b.height*b.width; i++) { for(int v=0; v<16; v++) { if(colors[v] == b.pixels[i]) { float a = amount[v]; a++; amount[v] = a; } } } // display results for(int v=0; v<16; v++) { print(red(colors[v])); print(green(colors[v])); print(blue(colors[v])); println(" percentage:" +amount[v]/480000*100+ " %"); } anyone know what the problem might be? yeah, i know the code ain't as sexy as could be, but then remember i'm a newbie . another thing: how can i set the code to be displayed like in Markavians post? Something like <code></code>? thx, Greg
|
|
|
|
mattgilbert
|
Re: color proportions
« Reply #4 on: Jun 11th, 2004, 10:05pm » |
|
Hi Greg, I handled a similar problem not long ago, so it was easy to combine my code and yours to show you how I did it. This code should do what you want. It's not as long as it looks; I just put lots of comments in. Hopefully they make sense. But I haven't tested it, so don't be surprised if there are typos or anything. In my code, I cycle through pixels[] finding the colors and keeping track of their amounts at the same time. If the pixel's color hasn't been found before, I start keeping track of it, and if it has been found before, I add 1 to that color's amount. on Jun 11th, 2004, 3:39pm, dek wrote: Code: // this script (should) work for a gif-image containing 16 colors, just for testing // i don't know yet how many different colors it could manage without the CPU going bananas float[] amount = new float[16]; color[] colors = new color[16]; // "empty" colors[] for(int i=0; i<16; i++) { colors[i] = 0; } BImage b; b = loadImage("lava16colors.gif"); size(b.width, b.height); image(b, 0, 0); // MATT: // here's my replacement for the color finding and // amount counting parts of your code. this code // should do both. for(int i=0; i<b.pixels.length; i++) { //the foundBefore variable will tell us whether or //not we've found the current pixel's color in colors[] yet. boolean foundBefore = false; //cycle through colors[] for(int u=0; u<16; u++) { //only check if we haven't found the pixel's //color in colors[] yet. Otherwise, do nothing. if(!foundBefore){ //if the colors[u] element is zero, then //we must not have found the color yet. We can //use colors[u] to store the color of b.pixel[i] //and start keeping track of the amount in //amount[u]. Also, we need to set foundBefore to true //so we don't check anymore. if(colors[u] == 0) { colors[u] = b.pixels[i]; amount[u] = 1; foundBefore = true; } //if the colors[u] element matches the color of //b.pixels[i], then we have found this color //before, and we only need to add one to the amount //and set foundBefore to true. else if(colors[u] == b.pixels[i]) { amount[u]++; foundBefore = true; } //if colors[u] isn't zero or the current color, //then continue the loop and check the next colors[] element. } } } // display results // MATT: // I changed how the percentage is calculated to just // be 100*amount[v]/b.pixels.length . I'm not sure // why you had amount[v]/480000*100 . for(int v=0; v<16; v++) { print(red(colors[v])); print(green(colors[v])); print(blue(colors[v])); println(" percentage:" +100*amount[v]/b.pixels.length+ " %"); } |
| |
| To do the code thing in the message board, use [ code ] at the beginning and [ / code ] at the end of your code, except without the spaces. Hope that helps. Matt
|
|
|
|
dek
|
Re: color proportions
« Reply #5 on: Jun 11th, 2004, 10:42pm » |
|
hey Matt, wow, that's more than i could have wished for. works perfect. 480000 is the total amount of pixels (my gif is 800x600), and yeah, it's rather confusing if one doesn't know. shows i should try to keep my code more general. now for the code thing: Code: it works! muchos gracias, Greg
|
|
|
|
dek
|
Re: color proportions
« Reply #6 on: Jun 14th, 2004, 11:43pm » |
|
me. again. so far i've got the program to calculate the colors and amounts (with a lot of help by Markavian and Matt), but now i want to visualize the results. a really easy way is to have a xyz-grid, where the x-axis is red, the y-axis is green and the z-axis is blue from the according color, a basic rgb-cube. then i draw a box at the according coordinates. the size of the box is determined by the amount of the color. that's simple enough. the whole color-model rotates around a vertical axis. i managed to lay the vertical axis through the y-axis and anywhere parallel to it, but never through the very center of the color-model. my main goal is it to rotate the model around it's center-point, mouse-controlled. but i'll never get that if i don't manage to set the center-point. i've tried various translations and push 'n' pops, but i just don't seem to have the hang of that yet, and i guess the mistake must hide somewhere there. the whole setup runs ok, it's the loop that's causing the headache: Code: // feed the sketch any .gif with a maximum color count of 256. // all colors are traced and their according amount is calculated. int n = 256; // number of different colors in the image, important! float a; float[] amount = new float[n]; color[] colors = new color[n]; void setup() { size(500, 500); for(int i=0; i<16; i++) { colors[i] = 0; } BImage b; b = loadImage("lava256colors.gif"); for(int i=0; i<b.pixels.length; i++) { boolean foundBefore = false; for(int u=0; u<n; u++) { if(!foundBefore){ if(colors[u] == 0) { colors[u] = b.pixels[i]; amount[u] = 1; foundBefore = true; } else if(colors[u] == b.pixels[i]) { amount[u]++; foundBefore = true; } } } } } void loop() { background(255); // rotate a += 0.05; if(a > TWO_PI) { a = 0.0; } translate(width/2, height/2, 0); rotateY(a); // center rgb-cube. it should. but doesn't. translate(-255/2, -255/2, 255/2); // whats wrong? // draw rgb-cube for(int v=0; v<n; v++) { push(); if (mousePressed == true) { noFill(); stroke(red(colors[v]), green(colors[v]), blue(colors[v])); // draw wireframe } else { fill(red(colors[v]), green(colors[v]), blue(colors[v])); // draw solids noStroke(); } translate(red(colors[v])/2, green(colors[v])/2, blue(colors[v])/2); box(amount[v]/500); pop(); } } |
| anyone got a hint where i made a wrong turn? tack, Greg
|
|
|
|
dek
|
Re: color proportions
« Reply #7 on: Jun 16th, 2004, 2:56pm » |
|
ignore my last post, problem solved.
|
|
|
|
|