How to locate colored pixel

Hi, im working with .png types and need help how to find the x,y location of certain colored pixels.
my png has two green pixels (0,255,0) that i need to locate, so i can set the connection points for the next png to it. its picked randomly from an array, so the location is not always the same. Is there a way to do it with the get() function? thanks in advance

1 Like

You could create a function that searches the image for a certain color by looking at all the pixels. Here’s how I would go about it:

function findPixelLocations(img, colorToFind) {
  let found = [];
  // will return an array of p5.Vectors with an empty array if nothing found
  for (let x = 0; x < img.width; x++) {
    for (let y = 0; y < img.height; y++) {
    // nested for loop checks all pixels
      let currentColor = get(x, y);
      // if statement checks red green and blue values of your currentColor vs the colorToFind
      if (red(currentColor) === red(colorToFind)
          && green(currentColor) === green(colorToFind)
          && blue(currentColor) === blue(colorToFind)) {
        found.push(createVector(x, y);
        // if the rgb values are the same it will add the a new vector with the x and y to the found array
      }
    }
  }
  return found;
}

95% sure this will work. You might have to change the lines in the if statement from red(currentColor) to currentColor.r and so on. Look at the pixel array documentation for more ideas on making this faster. But if you’re doing this every frame it might be slow. You can use processing for better performance. Also you might want to check out this tutorial by Dan Shiffman on the pixels array.

1 Like

thanks for that! But oh dear, thats some p5 stuff. Does that work on p3? i just started with processing3 and am very limited with it. I try to put it together but it seems to be little different.

from reference:
https://processing.org/reference/get_.html
example:
https://processing.org/examples/pixelarray.html

yeah im familiar with that but i need the opposite. In the example the pixel location is given and the color is displayed, but i need to locate the pixel without knowing the coordinates. There seems to be a way by scanning every pixel for its color by Daniel Schiffman but it is for video and i also cant find a reference

the point was to show you the

get()

function in processing java ( and that it is very similar to p5.js version )

PImage img;

void setup() {
  size(640, 360);
  img = loadImage("data/moonwalk.jpg");
  noFill();
  noLoop();
  stroke(200, 0, 0);
  strokeWeight(3);
}

void draw() { 
  image(img, 0, 0);
  for ( int x =0; x< img.width; x++)
    for ( int y =0; y< img.height; y++) {
      color pix = img.get(x, y);
      int r = int(red(pix));
      int g = int(green(pix));
      int b = int(blue(pix));
      if ( r < 127 && g >= 127 && b < 127 ) {
        circle(x, y, 10);
        println(x, y, r, g, b);
      }
    }
}

scanning the whole picture with get is slow, better, but more difficult
https://processing.org/reference/loadPixels_.html
https://processing.org/reference/pixels.html

2 Likes

Thank you! Thats it! Have a nice day

If you need even better performance, you can improve it by:

  1. don’t use get() – use loadPixels

  2. don’t use green() red() blue() – you are searching for an exact value, so you can just compare the two integers, if(c1==c2). If you do need to check individual channels or introduce a fudge factor, speed up color retrieval using bit shifting, as per their reference pages:

    int r = c >> 16 & 0xFF;
    int g = c >> 8 & 0xFF;
    int b = c & 0xFF;
    
  3. if you need multiple matches, search from an arbitrary starting point (your last result). Then you can gather your matches in a batch.

// 2019-04 MatchPixels - Processing 3.4
// discourse.processing.org/t/how-to-locate-colored-pixel/9902
PImage img; 
int markerColor = color(255, 0, 0);

void setup() {
  size(100, 100);
  img = createImage(100, 100, ARGB);
  img.loadPixels();
  // mark three random pixels
  for (int i=0; i<3; i++) {
    img.pixels[(int)random(img.pixels.length)] = markerColor;
  }
  img.updatePixels();
  noLoop();
}

void draw() {
  background(255);
  image(img, 0, 0);

  // find a marker
  int px = matchPixel(img, markerColor, 0);
  if (px != -1) {
    println(px);
    println(xy(img, px));
  }

  // find all the markers
  IntList matches = matchPixels(img, markerColor);
  println(matches);
  for (int i : matches) {
    println(xy(img, i));
  }
}

int matchPixel(PImage img, color c, int startIndex) {
  img.loadPixels();
  for (int i=startIndex; i<img.pixels.length; i++) {
    if (img.pixels[i] == c) {
      return i;
    }
  }
  return -1;
}

IntList matchPixels(PImage img, color c) {
  int startIndex = 0;
  IntList matches = new IntList();
  while (startIndex < img.pixels.length) {
    int result = matchPixel(img, c, startIndex);
    if (result == -1) break;
    matches.append(result);
    startIndex = result+1;
  }
  return matches;
}

PVector xy(PImage img, int index) {
  int x = index%img.width;
  int y = (img.pixels.length-x)/img.height;
  return new PVector(x, y);
}
2 Likes

wow thanks ill try that