Errors when cycling through pixels[]

edited February 2016 in Questions about Code

I've been delving into image processing over the last few days and thought I had an idea of what was going on, but apparently I'm doing something very wrong. Whenever I run my code, Processing locks up and I have to force quit. It's frustrating.

I've stripped down some code I'm working on to figure out what's breaking, but even in this VERY bare bones version, everything breaks. At this point I'm simply trying to cycle through each pixel and report red green and blue values. Any help would be greatly appreciated as I have no idea what I'm doing incorrectly.

code below

PImage source;
int loc;
float r;
float g;
float b;
float lumin;
color c;

void setup(){
 source = loadImage("sheet_face.jpg","jpg");
 size(564,848,P2D); 
 float threshold = .7;

 source.loadPixels();

 image(source,0,0);

 for(int y = 0; y < source.height; y++){
  for(int x = 0; x < source.width; x++){
   loc = y*width+x;
   c = source.pixels[loc];
   r = red(c);
   g = green(c);
   b = blue(c);
   println("red value is "+r);
   println("green value is "+g);
   println("blue value is "+b);
   lumin = (r+g+b)/765;
   println("lumin value is "+lumin);
  }
 }
 source.updatePixels();
}

Answers

  • edited February 2016

    Just a quick guess: you need to use loc = y*height+x;, as you loop through rows first.

  • That didn't make sense to me, but I gave it a try anyway. No dice. Even if I got rid of that and just used get(x,y) instead, it still locks up.

  • Oddly enough, this code DOES work with smaller for loop limit values. If I set x < 30 and y < 30, it runs fine. Using source.height does not, nor does hardcoding the actual height of the image I'm using. Setting a big number (like 300) also breaks it. It makes no sense to me.

  • edited February 2016

    There's a sense, cause at some point you're trying to access the element in pixels array that does not exist. I mean, just looping through all the pixels in the image should look like:

    for (int i = 0; i < source.pixels.length; i++){
    color c = source.pixels[i];
    r = red(c);
    println("pixel" + i + " red value is "+r);
    }
    

    This should work for sure.

  • I tried changing to just one loop using the single loop and source.pixels[i] and it still didn't work. Aside from this, shouldn't I just get the typical "out of bounds" error if I was trying to access non-existent pixels? Right now I get no error message...just freezing and non-responsiveness.

  • Answer ✓

    Be careful of using too much output - processing sometimes has problems if you write too much to the console.

    Y * width + x is correct fwiw

  • Oh, and I've just noticed, try to use draw function, instead of doing everything in setup

  • edited February 2016 Answer ✓

    Too many print() commands within a short amount of time halts the whole sketch! :-SS

  • AH HA! Getting rid of the println() seems to make it work. That said, if I DID want to have all those values to look over, is there a better way to do this? Should I export the values to a text file or something instead?

  • Oh, and I've just noticed, try to use draw function, instead of doing everything in setup

    Not in this case. Draw continuously executes, up to 60 times a second. He wants to run through the image once and then stop so setup is fine.

  • Ater, I might be missing something, but why wouldn't doing everything in setup work? I was under the impression that draw is only used when you want to perform functions on repeat (as is often the case with animation). In this case, I really only need to scan through the pixels once to do analysis and manipulation, in which case setup should work, although I'm not sure if maybe there's a function that for whatever reason won't work in setup?

  • Nevermind, I just load a picture from the internet, so it may not load in setup until I try to access pixels. That was println, good that it works now.

  • edited February 2016

    Should I export the values to a text file or something instead?

    /**
     * Luminosity Average (v1.02)
     * GoToLoop (2016-Feb-22)
     *
     * forum.Processing.org/two/discussion/15050/errors-when-cycling-through-pixels
     * forum.Processing.org/two/discussion/13792/color-bit-shifting
     */
    
    static final float LUMIN = 3 * 0xFF;
    float[] lumins;
    PImage img;
    
    void settings() {
      img = loadImage("sheet_face.jpg");
      lumins = new float[img.pixels.length];
    
      size(img.width, img.height);
      noLoop();
    
      println(img.width, img.height, width, height, lumins.length, ENTER);
    }
    
    void draw() {
      background(img);
    
      final int p[] = img.pixels, len = p.length, rgb[] = new int[3];
    
      for (int i = 0; i < len; ++i) {
        to_RGB_array(p[i], rgb);
        lumins[i] = (rgb[0] + rgb[1] + rgb[2]) / LUMIN;
      }
    
      for (int i = 0; i < len; i += 1000)  println(i, lumins[i]);
    }
    
    static final int[] to_RGB_array(final color c, final int... target) {
      final int r = c >> 020 & 0xff;
      final int g = c >> 010 & 0xff;
      final int b = c        & 0xff;
    
      if (target == null || target.length < 3)  return new int[] {r, g, b};
    
      target[0] = r;
      target[1] = g;
      target[2] = b;
    
      return target;
    }
    
  • GoToLoop, that was also me ;)

Sign In or Register to comment.