Loading...
Logo
Processing Forum

Access image pixels

in Programming Questions  •  1 year ago  
Hello i'm new to processing and i've no programming background.
I'm using processing to make things related to design.

So here is my question:
1. I want to analyse images accessing each pixel;
2. Store de RBG value of each pixel;
3. Calculate the average of each color value;
4. Fill the screen with the average color;
5. In the future i want the 2nd and 3rd most used colors too, but now i'm happy with one color;

I'm very basic with this language.
I've started with the code above and i want to develop it gradually if anyone can help.

Thanks

-----------------------

PImage img;
color [] imageColors;

void setup() {
  size(533, 750);
  background(0);
  smooth();
  img = loadImage( "almanaque.jpg");
}

void draw() {
  loadPixels ();
  img.loadPixels ();

  // search each line and row of the image
  for (int x=0; x < img.width; x++) {
    for (int y=0; y < img.height; y++) {
      int loc = x + y*img.width;

      float r = red (img.pixels [loc]);
      float g = green (img.pixels [loc]);
      float b = blue (img.pixels [loc]);
    }
  }
}

Replies(10)

Problem / Notes:

I'm not sure what exactly you're having trouble with, so I'll go down the list and comment on better ways to do this...

You shouldn't put the code that you have in draw() in draw(); you only need to do that once (put it in setup()).
You should close the img.loadPixels() call with the opposite, img.updatePixels().
Then, you should add the color to your list of colors...
Prior to doing this, however, you must initialize that array...

Let's get started with this:

Final Code:

Copy code
  1. PImage img;
  2. color [] imageColors;

  3. void setup() {
  4.   size(533, 750);
  5.   background(0);
  6.   smooth();
  7.   img = loadImage( "almanaque.jpg");
  8.  
  9.   img.loadPixels();
  10.  
  11.   imageColors = new color[image.pixels.length];
  12.  
  13.   // search each line and row of the image
  14.   for (int x=0; x < img.width; x++) {
  15.     for (int y=0; y < img.height; y++) {
  16.       int loc = x + y*img.width;
  17.       float r = red (img.pixels [loc]);
  18.       float g = green (img.pixels [loc]);
  19.       float b = blue (img.pixels [loc]);
  20.      
  21.       imageColors[loc] = color(r, g, b);
  22.     }
  23.   }
  24.  
  25.   img.updatePixels();
  26. }

  27. void draw() {
  28. }

Look at that for now and get started on averaging the colors...
Ok. Thanks a lot for your help.
To start, i need to average every "R" values, adding all R values of the pixels of the image?
Storing that values in a global variable and then dividing it by the array length?
Where i do that? Inside de for loop who search every row and collum of the image?

I'm sorry for my level of skill, but i want to learn and understand every step of the code.
Probably i'm trying to make a big thing with little knowledge.

Thanks again.
Well...
Now that you have an array of colors, you can cycle through it...
Like this:

Copy code
  1. for(int i = 0; i < imageColors.length; i ++) {
  2.   //Do stuff
  3. }

In this case, you're going to want to find the sum of each of the colors...
So, create three integers outside of the for loop: an r, g, and b.
Then, in each stage of the for loop, add the current rgb values to the respective variables.
After that, divide them... and you have your averaged color.
It´s something like this?
I've created the global int r, g, b.

// search each line and row of the image
  for (int x=0; x < img.width; x++) {
    for (int y=0; y < img.height; y++) {
      int loc = x + y*img.width;

      for (int i=0; i < imageColors.length; i++) {
        r = red (img.pixels [loc]);
      }
        
        float g = green (img.pixels [loc]);
        float b = blue (img.pixels [loc]);

        imageColors[loc] = color (r, g, b);


      }
    }
Argh! My computer crashed and thus I lost my message...
Anyway, to sum it up:

Put that for loop after last set brace of the two nested for loops...
And you don't need to store the three variables globally.

I'm currently writing an example for averaging...
Here's the example:
You should be able to adapt it to work with three numbers instead of just one...

Copy code
  1. //List of numbers
  2. int[] numbers = {54, 13, -76, 122, 66, 59};
  3. //Setup
  4. void setup() {
  5.   size(200, 200);
  6.  
  7.   //Find the average of the numbers
  8.   int average = averageNumbers(numbers);
  9.   //Print it to the console
  10.   println(average);
  11. }
  12. //Function to find average numbers
  13. int averageNumbers(int[] nums) {
  14.   //The total
  15.   int total = 0;
  16.   //Cycle through the provided numbers
  17.   for(int i = 0; i < nums.length; i ++) {
  18.     //Add the current number to the total
  19.     total += nums[i];
  20.   }
  21.  
  22.   //Return the total divided by the number of items (the average)
  23.   return total / nums.length;
  24. }
Ok, thanks for your example. I understand it.
I created a function to calculate the average of R color and total.
But the printl give a value of 556. The value should be between 0-255, right?
Why it give this value?


PImage img;
color [] imageColors;

void setup() {
  size(533, 750);
  background(0);
  smooth();
  img = loadImage( "almanaque.jpg");

  img.loadPixels ();

  imageColors = new color [img.pixels.length];

  // search each line and row of the image
  for (int x=0; x < img.width; x++) {
    for (int y=0; y < img.height; y++) {
      int loc = x + y*img.width;

      float r = red (img.pixels [loc]);
      float g = green (img.pixels [loc]);
      float b = blue (img.pixels [loc]);

      imageColors[loc] = color (r, g, b);
    }
  }
  // find average of R
  int averageR = averageRcolor(imageColors);

  println (averageR);

  img.updatePixels ();
}



// function to find average of R color
int averageRcolor (int[] rvalues) {
  //total
  int totalR = 0;
  //cicle through R values
  for (int i=0; i < rvalues.length; i++) {
    totalR += rvalues[i];
  }

  return totalR/rvalues.length;
}

void draw() {
}

Oh i forget to specify what color he calculates the average...
That's here i put that? How? (I call the array imageColors and i must tell to the program, what color???)

 int averageR = averageRcolor(imageColors);
When dealing with colors, you should add the read, green, and blue values separately.
That means three variables... three divisions... etc.
Hi.
At this point i've calculated one color value.
Can i calculate the other values in the same function, "medR_"? Or i've to create 3 different functions?
If i put the return values in a global variable, i can use them to fill forms, right?

---

PImage img;
color [] imageColors;
int medR = 0;

void setup() {
  size(533, 750);
  background(0);
  smooth();
  img = loadImage( "almanaque.jpg");

  img.loadPixels ();

  //New list with colors?
  imageColors = new color [img.pixels.length];

  // search each line and row of the image
  for (int x=0; x < img.width; x++) {
    for (int y=0; y < img.height; y++) {
      int loc = x + y*img.width;

      float r = red (img.pixels [loc]);
      float g = green (img.pixels [loc]);
      float b = blue (img.pixels [loc]);

      imageColors[loc] = color (r, g, b);
    }
  }
  // find average of RGB
  medR = medR_(imageColors);
println (medR);
  img.updatePixels ();
}

// function to find average of R color
int medR_ (int[] rvalues) {
  //total
  int totalR = 0;
  //cicle through R values
  for (int i=0; i < rvalues.length; i++) {
    totalR += blue (rvalues[i]);
  }
  return totalR/rvalues.length;
}


void draw() {
  fill (204, 126, 124);
  rect (0, 0, width, height);
}