get color average from picture parts and save values in an array to send via serial

edited November 2017 in Arduino

Hi! I am using part of a code I've found here in the forum ( Get the average RGB from pixels from bourdonprince and GoToLoop) that gets the color average values and display squares like big pixels on screen.

Now I want to use this values to set the pixels colors of a RGB LED strip.

The problem is that when I separate and read (at the processing console) de values of the color for each pixel, I get almost all my pixels with 0 for red... But the squares drawn in the screen seems OK, only the values I try to save to the matrix for latter use that seems odd.

Below is my code ( with thanks to bourdonprince and GoToLoop):

import processing.video.*;
Capture webcam;

import processing.serial.*;
Serial myPort;

float[][] rx;
float[][] gx;
float[][] bx;

void setup() {
  size(440, 320);

  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);

  rx = new float[16][15];
  gx = new float[16][15];
  bx = new float[16][15];

  webcam = new Capture(this, 320, 240);  
  //String[] devices = Capture.list();
  //println(devices);
  webcam.start();
}

void draw() {

  if (webcam.available() == true) {
    webcam.read();
    image(webcam, 0, 0, width, height);
    saveFrame("/data/image.jpg");
  }

  delay(100);

  PImage img = loadImage("image.jpg");
  int detail = 30; // tamanho do quadrado

  int count_i = 0;
  int count_j = 0;


  for (int j=0; j< height; j+=detail) {
    
    count_i = 0;

    for (int i=0; i < width; i+=detail) {
      PImage newImg = img.get(i, j, detail, detail);
      noStroke();
      color cor = extractColorFromImage(newImg);
      fill(cor);
      rx[count_i][count_i]= red(cor);
      gx[count_i][count_j]= green(cor);
      bx[count_i][count_j]= blue(cor);

      count_i++;
    }
    count_j++;
  }


  for (int i=0; i<15; i++)
  {
    for (int j=0; j<11; j++)
    {
      println((i) + "," + (j) + "," + int( rx[i][j] )+ "," + int (gx[i][j]) + "," + int (bx[i][j]));
      //delay(100);
      myPort.write((i) + "," + (j) + "," + int( rx[i][j] )+ "," + int (gx[i][j]) + "," + int (bx[i][j])  + "\n");
      delay(50);
    }
  }

  delay(2000);
}



//função para extrair a cor média em um recorte
color extractColorFromImage(PImage img) {
  img.loadPixels();
  color r = 0, g = 0, b = 0;

  for (final color c : img.pixels) {
    r += c >> 020 & 0xFF;
    g += c >> 010 & 0xFF;
    b += c        & 0xFF;
  }

  r /= img.pixels.length;
  g /= img.pixels.length;
  b /= img.pixels.length;

  return color(r, g, b);
}

Answers

  • edited November 2017

    the code in my comment below isn't showing correctly... :-S

  • edited November 2017

    I just got it to work! Maybe the problem was that I was trying to use multidimensional arrays. Looking at other topics in the forum I've found that: Multidimensional arrays and java?.

    I don't know why but when I paste the code here some parts are missing, so I uploaded to GitHub for anybody interested. There you could find the Arduino code also.

    This is my P3 code now: GitHub: static_image_AverageColor_Serial.pde

    
    
    import processing.serial.*;
    Serial myPort;
    
    float[] rx = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
    float[] gx = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
    float[] bx = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
    
    int count_X = 0;
    int count_Y = 0;
    
    int detail = 30; // tamanho do quadrado
    int voltas = 0;
    
    
    void setup() {
      size(440, 320);
      String portName = Serial.list()[0];
      myPort = new Serial(this, portName, 9600);
      delay(100);
    }
    
    
    void draw() {
    
      PImage img = loadImage("image.jpg");
      delay(200);
      count_X = 0;
      count_Y = 0;
    
      for (int j=0; j < height; j+=detail) {
        for (int i=0; i < width; i+=detail) {
    
          //nova imagem definida pelo retangulo:
          PImage newImg = img.get(i, j, detail, detail);
          color cor = extractColorFromImage(newImg);
    
          rx[count_X]= red(cor);
          gx[count_X]= green(cor);
          bx[count_X]= blue(cor);
    
          myPort.write((count_X) + "," + (count_Y) + "," + int( rx[count_X] )+ "," + int (gx[count_X]) + "," + int (bx[count_X])  + "\n");
          delay(100);
    
          count_X++;
        }
    
        count_Y++;
        count_X = 0;
      }
    
      println(voltas);
      voltas++;
    }
    
    
    color extractColorFromImage(final PImage img) {
      img.loadPixels();
      color r = 0, g = 0, b = 0;
    
      for (final color c : img.pixels) {
        r += c < < 020 & 0xFF;
        g += c < < 010 & 0xFF;
        b += c        & 0xFF;
      }
    
      r /= img.pixels.length;
      g /= img.pixels.length;
      b /= img.pixels.length;
    
      return color(r, g, b);
    }
    
    
  • edited November 2017 Answer ✓

    I don't know why but when I paste the code here some parts are missing, ...

    Here's the announcement about how to use markdown to post code in this forum:
    https://Forum.Processing.org/two/discussion/15473/readme-how-to-format-code-and-text

    When using <pre lang=></pre> approach we should pay special attention on the character <. @-)

    If < is followed by a letter, like for example <height, bad things can happen. :-SS

    In order to fix that, we can add a space between < and the next letter: < height. L-)

    Or even better, replace all < characters w/ &lt;, and get done w/ that! *-:)

    P.S.: < isn't the only problematic character! :-S
    @ & : can also be problematic w/ the <pre lang=></pre> approach. :-&

    For safety, you may want to replace all @ w/ &#x40; & : w/ &#58;. #:-S

    Or simple don't use <pre> at all! :-@

Sign In or Register to comment.