color range checking

edited September 2017 in How To...

I want to check if the returned value read from a gray level image ( 0-255) image is a graylevel and not a color. I paint blob objects red with threshold filter and i want to skip over that red part. SO... if img.pixels[loc] >> 8 & 0xFF is not a color then ... Can i check the result for between 0,0,0 - 255,255,255 grayscale only , so a color of 0,255,0 would not be true?

still trying to understand what the color values return and how to decipher them thanks

Answers

  • edited September 2017

    For a white/grey/black color, you would expect the red, green, and blue amounts in that color to be about the same. For a red color, you would expect the red amount to be a lot larger.

    size(600,400);
    background(0);
    color[] cs = new color[3];
    cs[0] = color(128); // grey
    cs[1] = color(200); // whitish
    cs[2] = color(200, 0, 0); // redish
    
    for ( int i = 0; i < cs.length; i++) {
      fill(cs[i]);
      if ( abs( red(cs[i]) - green(cs[i]) ) < 2 && abs( red(cs[i]) - blue(cs[i]) ) < 2) {
        text( "Color #" + i + " appears to be a greyscale color.", 20, 20 + 20 * i);
      } else {
        text( "Color #" + i + " appears to be more of a red color.", 20, 20 + 20 * i );
      }
    }
    
  • There is a function red() that returns the red value of a color

    Maybe you can use this and check if this gives 0

    Also look at brightness

    Also maybe for gray red () == blue() == green () ? Test it

  • edited September 2017 Answer ✓

    Is this literally a grayscale image that you have modified -- that is, was the file saved in grayscale mode before being loaded in Processing? Or is it an RGB image of grayscale subject matter -- like a color photo of a black and white newspaper?

    If you are painting blobs, it sounds like it could be a graylevel realtime camera. In that case you need speed, and bit-level equality checking is much faster than using color channel functions to do inequality checking on ints (although it is still essentially the same as @TfGuy44 's algorithm above).

    Processing's color format in an int is ( https://processing.org/reference/color_datatype.html ):

    AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB
    

    For speed you can access the colors through bitshifting ( https://processing.org/reference/rightshift.html )

    int r = (argb >> 16) & 0xFF;  // Faster way of getting red(argb)
    int g = (argb >> 8) & 0xFF;   // Faster way of getting green(argb)
    int b = argb & 0xFF;          // Faster way of getting blue(argb)
    

    So:

    boolean graypixel (int p){
      if( (p>>16) == (p>>8) && (p>>8) == (p>>0xFF) ){ // R = G, G = B
        return true;
      }
      return false;
    }
    
    void checkPixels (){
      loadPixels();
      for (int i = 0; i < (width*height/2)-width/2; i++) {
        if graypixel(pixels[i]){
          // gray!
        }
        // color!
      }
      updatePixels();
    }
    

    Note that the graypixel inequality line will fail immediately on R!=G, then check G=B if the first check passes. If you are only using a red channel, you can just drop the second half of the if test for even better performance.

    For even better performance (I suspect, untested), draw the video on top of a red background(), and set the alpha of blob pixels to transparent -- don't colorize them, fade them. Now blobs still show as red, but you can check one pixel bit region -- the alpha channel of each pixel -- for blob classification, and you still have all the original grayscale information in there if you need it for anything else.

Sign In or Register to comment.