1

I'm currently trying to consistently monitor a specific area of a PImage for it's color values, and pull XY coordinates of the first pixel to flag a change.

Example: A thresholded video is playing, I want to monitor a specific area, and pull the coordinates of the first pixel that changes from black to white. This will be used for a rudimentary collision detection/reaction.

I can call the PImage.get() function, and return the range of pixels that I want to monitor, but I cannot figure out what kind of data is stored in the resulting array.

Right now I just have (mostly for troubleshooting, that won't be in the final code)

printArray(colTest.get(box.bx, box.by, box.bW, box.bH));

just to show me the data but I cannot figure out what kind of data it is for me to actually run analysis on it.

The data from the PImage.get(x,y) is in readable color data, but the PImage.get(x,y,length,width) returns something like this:

processing.core.PImage@693b37ff
processing.core.PImage@607f247e
processing.core.PImage@677753c3
processing.core.PImage@1474d906
processing.core.PImage@13ef5435
processing.core.PImage@7a9ed6d7
processing.core.PImage@4e0c4bff
processing.core.PImage@4151f866
processing.core.PImage@6ad24b6a
processing.core.PImage@539fb47b
processing.core.PImage@2f0d635d
processing.core.PImage@251de095
processing.core.PImage@b5745d
processing.core.PImage@20991a01
processing.core.PImage@42b10fa9

...

Looking into the PImage.get(range) function, it returns a PImage. I'm wondering if there's a way to decode that data into either color or alpha data.

This goes on (non-repeating from what it seems) forever until the video loops. I've called the PImage.pixel[] array, but it is just so much data that I think it'll slow me down too much to have to comb through it every frame. My theory is that it would be much easier on the processor to just monitor a specific area (or areas) and return just those values rather than updating, accessing, analyzing, and returning results from the entire Pixel[] array every frame.

In order to reproduce this output, you can use this:

PImage img;

void setup() {
    size(500, 500);
    
    img = createImage(250, 250, RGB);
    
    img.loadPixels();
    for (int i = 0; i < img.pixels.length; i++) {
        img.pixels[i] = color(0);
    }
    
    imageMode(CENTER);
    
    img.updatePixels();
}

void draw() {
    
    image(img, width / 2, height / 2);
    
    println(img.get((width / 2),(height / 2), 50, 50));
}
  • As per [the docs](https://processing.org/reference/get_.html), without width and height, it gets a pixels[x][y] as color int. With explicit width and height, it returns "another PImage" but cropped to your area of interest, at the time you called it (so if the pixels in the original image change, the derivative PImage does _not_ also change). – Mike 'Pomax' Kamermans Mar 16 '23 at 23:08
  • What do you mean with "I'm currently trying to consistently monitor a specific area of a PImage", though? Images are static, their pixels don't change from frame to frame. If you're comparing separate frames, though, you could use a tiny PGraphics (created with `createGraphics`) that you [blend](https://processing.org/reference/blendMode_.html) your frames on and then check _that_ PGraphics' pixels. Because image drawing is fast. – Mike 'Pomax' Kamermans Mar 16 '23 at 23:15
  • @Mike I suppose I should have been more specific in that I'm trying to monitor the pixels of a moving image. I'm running a testing ground right now that's using the Movie class which get() returns a PImage. So I'm trying to decipher the PImage data. Also if the get() function is called in draw() it should update every frame, right? I'm counting on that so I can detect when a pixel changes. There's also a solid chance I'm way off base, so if there's a more efficient solution I'm definitely open to suggestions. – Spenser Spratlin Mar 17 '23 at 02:44
  • 2
    You probably want to show a [mcve] of your code here, to sketch a "technically precise" picture, but it sounds like what you want is a double frame buffer for just the part of the video you're interested in so you can draw both the current frame and the previous frame on a separate PGraphics with subtract mode (that way, pixels that stay the same cancel out, pixels that changed don't) – Mike 'Pomax' Kamermans Mar 17 '23 at 06:06
  • Just updated the post with a code that has the same style output. – Spenser Spratlin Mar 17 '23 at 14:11
  • change that `println(img.get((width / 2),(height / 2), 50, 50));` to `println(frameRate, img.get((width / 2),(height / 2), 50, 50));`, I'm getting 60fps on this code by default, and if I add `frameRate(240)` in my setup, I also get 240 during draw. Which makes sense, because there's nothing really expensive about this code. – Mike 'Pomax' Kamermans Mar 17 '23 at 18:06
  • What does changing my frame rate have to do with the question, though? I was just wondering what kind of data the println(Pimage) was producing. I did find a different solution, though. I called the pixel array for the PImage returned from the get() function, translated it into Brightness values from 0-255, and pulled the coordinates from the location in the array. – Spenser Spratlin Mar 19 '23 at 17:02
  • It has to do with "knowing whether an operation is slow or not" because if you can work "inefficiently" with the pixel array because your frameRate value says you're still running at 60 fps when you do so, then there is no reason to even bother optimizing that code. As such, knowing what framerates you get, and thus whether it even makes sense to figure out what's in PImage, is a fairly important step in the whole "implementing what you want to do" process. – Mike 'Pomax' Kamermans Mar 19 '23 at 18:57
  • (Because of course in terms of "what's in this object", the answer is "read [the docs](https://processing.org/reference/PImage.html), it tells you exactly what's in it and how you access that" =) – Mike 'Pomax' Kamermans Mar 19 '23 at 19:00
  • For future reference, if anyone ends up here in the future, I never was able to translate the dataype in the first code block, unfortunately. In order to access the pixel information that I needed, I realized I was able to call the pixel array for the smaller PImage that PImage.get(); produces. – Spenser Spratlin Apr 07 '23 at 18:53

0 Answers0