How can I count white pixels of an image?

Hey! So i have this assignement where i need to create a binary image of what my computer camera catches and when i have more than 100 white pixels it should appear a message saying motion detected. The problem is I don’t know how can i count the amount of white pixels that appear.

Any help would be so very appreciated


import processing.video.*;
Capture cam;
PImage diference;
PImage frameAnt;
PImage binary;

float threshold = 50;
float pxWhite = 100;

void setup () {
  size(640, 240);

  cam = new Capture(this, 320, 240);
  diference = new PImage(320, 240);
  frameAnt = new PImage(320, 240);
  binary = new PImage(320, 240);

  cam.start();
}

void draw () {
  if (cam.available()) {
    cam.read(); 

    cam.loadPixels();
    diference.loadPixels();
    frameAnt.loadPixels();
    binary.loadPixels();

    for (int i = 0; i < cam.pixels.length; i++) {
      float cR = red(cam.pixels[i]);
      float cG = green(cam.pixels[i]);
      float cB = blue(cam.pixels[i]);

      float aR = red(frameAnt.pixels[i]);
      float aG = green(frameAnt.pixels[i]);
      float aB = blue(frameAnt.pixels[i]);

      diference.pixels[i] = color(cR-aR, cG-aG, cB-aB);
      
      float b = brightness(diference.pixels[i]);
      if(b > threshold)
      binary.pixels[i] = color(255);
      else
      binary.pixels[i] = color(0);
    }
    diference.updatePixels();
    frameAnt = cam.copy();
    binary.updatePixels();    
  }
  image(cam, 0, 0);
  image(binary, 320, 0);
}

Hi @bouu28,

Why not doing it a simple way…

  • Assuming you are using the default RGB colormode…
  • Create a variable and initialize it with the white color representation color(255)
  • Loop through the pixels array, like you are doing already above in your code and check if the current pixel value is equal (==) to the white variable value from above.
  • If equal increment a counter.
  • If you only need to check for a certain amount (ie. more than 100) you can check if the counter is above (>) that value and set a flag (ie boolean variable) to true and break out of the loop.
  • Do actions based on your flag which says more than 100 white pixels or not.

Hope that helps…

Cheers
— mnse

Or you use brightness (…) > 88 or so; due to antialising some white pixels might not have the exact value 255

Hmmm! I would keep it simple…

If the exercise says count white pixels and not count almost white pixels I wouldn’t mess around with stuff like antialiasing. But if the exercise says to consider a threshold to detect almost white pixels the brightness approach would be a good one …

Cheers
— mnse

3 Likes

Hey
So i’ve been trying all that i can remember and what you guys told me too but nothing is working. I’m probably doing something wrong but I don´t see where.
I don’t want to ask too much cause your help is already good for real but if anyone could share some code that might help with this I would me so grateful.
Thank you so much tho for your help.

Please post your entire code

Hi

Good reference

2 Likes

Here is the code that i have, this was my last try, i’m gonna try other way now

import processing.video.*;

Capture cam;
PImage difference;
PImage frameAnt;
PImage binary;

float threshold = 50;
//float pxBranco = 100;
Boolean pxBranco = true;

color white = color(255);
int count = 0;

void setup () {
  size(640, 240);

  //sqr = new SqrOsc(this);
  //sqr.play();

  cam = new Capture(this, 320, 240);
  difference = new PImage(320, 240);
  frameAnt = new PImage(320, 240);
  binary = new PImage(320, 240);

  cam.start();
}

void draw () {
  if (cam.available()) {
    cam.read();

    cam.loadPixels();
    difference.loadPixels();
    frameAnt.loadPixels();
    binary.loadPixels();



    for (int i = 0; i < cam.pixels.length; i++) {
      float cR = red(cam.pixels[i]);
      float cG = green(cam.pixels[i]);
      float cB = blue(cam.pixels[i]);

      float aR = red(frameAnt.pixels[i]);
      float aG = green(frameAnt.pixels[i]);
      float aB = blue(frameAnt.pixels[i]);

      difference.pixels[i] = color(cR-aR, cG-aG, cB-aB);

      float br = brightness(difference.pixels[i]);
      if (br > threshold)
        binary.pixels[i] = color(255);
      else
        binary.pixels[i] = color(0);
    }

    for (int x = 0; x < binary.width; x++) {
      for (int y = 0; y < binary.height; y++) {
        int loc = x + y * binary.width;
        if (binary.pixels[loc] == color(255)) {
          if (loc <= 100) {
            fill(250, 0, 0);
            square(width/2, height/2, 50);
          }
        }
      }
    }

    difference.updatePixels();
    frameAnt = cam.copy();

    binary.updatePixels();
  }
  image(cam, 0, 0);
  image(binary, 320, 0);
}
1 Like

Hello @bouu28,

Try moving this code (from your last post) to the end of draw() to see what it is doing:

  for (int x = 0; x < binary.width; x++) {
    for (int y = 0; y < binary.height; y++) {
      int loc = x + y * binary.width;
      if (binary.pixels[loc] == color(255)) {
        if (loc <= 100) {
          println(x, y);  // glv added to your code
          fill(250, 0, 0);
          square(width/2, height/2, 50);
        }
      }
    }
  }

You are displaying an image over the above code in your example!

The above code at the end of draw() displays a red square when there is motion at a loc <= 100 (in this case x<=100, y = 0).
I added a println() to display x, y to the console; this is a useful tool for examining and debugging code.

Note:
There is no anti-aliasing in the binary[] pixels array; it will only contain 0 or 255.
Do not concern yourself with this and stay on track.

Your code is already doing this:

if (br > threshold)
  binary.pixels[i] = color(255);
else
  binary.pixels[i] = color(0);

Consider adding a variable to also count these.

There are resources (tutorials, references and examples) here to peruse:

References:

There is an example that generates a histogram of all the brightness levels; try to glean some insight from this.

Try adding a variable to count the occurrences of 0 or 255 in this simple example:

int data [] = {0, 255, 0, 0, 255, 0, 255, 0, 0, 255};

for (int i=0; i<data.length; i++)
  {
  println(i, data[i]);
  }

And then apply that to your code.

Keep at it!

:)

3 Likes

Hello! So it finally worked :slight_smile: Thank you so much for your help, I’m really grateful

2 Likes