Tracking the good color

I’m building a code that will allow you to recognize color cards and, depending on the color, a drawing will appear in the drawing area.
Example:
red = red round
blue = blue round
green = green square

I was able to define my areas, but I can not ask him to display a shape when he tracks the right color.
I show you my code, my English is not great I hope you understand.

import processing.video.*;

Capture video;
PImage scanArea;

color[] palette = {color(28, 5, 253), 
  color(100, 205, 205), 
  color(100, 100, 100), 
  color(250, 5, 40), 
  color(0, 255, 0), 
  color(255, 255, 0)};
  
//color red = color(0,100,100);
color r;

color cible;
int proche;
int index;

int frameWidth  = 200; // largeur de la zone de scan
int frameHeight = 200; // hauteur de la zone de scan

Zone maZone1 = new Zone(10, 71, color(255));
Zone maZone2 = new Zone(10, 271, color(255));


void setup() {
  size(640, 480);

  video = new Capture(this, width, height);
  video.start();

  colorMode(HSB, 360, 100, 100);
  noStroke();

  scanArea = createImage(frameWidth, frameHeight, RGB);
}

void captureEvent(Capture video) {
  video.read(); // Lecture de l'image provenant de la camera
}

void draw() {
  video.loadPixels();

  if (video.available()) video.read(); // Update Capture

  pushMatrix();
  scale(-1, 1); // video en miroir 
  translate(-video.width, 0);
  image(video, 0, 0);
  popMatrix();


  if (frameCount % 50 == 0) { // Scan sans arret image par image 
    scanArea.copy(video, 200, 200, frameWidth, frameHeight, 0, 0, frameWidth, frameHeight);
  }

  proche = 360;
  index = 0;

  maZone1.display(); // affiche la zone de scan 1
  maZone2.display(); // affiche la zone de scan 2
  structure(); 


  if (mouseX > 10 && mouseX < 210 && mouseY > 71 && mouseY < 275) { 
    couleurCible1(get(mouseX, mouseY)); // couleur comparee, ciblée
    for (int i= 0; i < palette.length; i++) {
      int c = int(hue(palette[i])); 
      int distance = abs(c - int(hue(cible)));
      if (distance < proche) {
        proche = distance; 
        index = i;
      }
    }
    fill(0);
    ellipse(index * 20 + 90, 30, 10, 10); // pointeur
  }
  
  if (mouseX > 10 && mouseX < 210 && mouseY > 271 && mouseY < 492) { 
    couleurCible2(get(mouseX, mouseY)); // couleur comparee, ciblée
    for (int i= 0; i < palette.length; i++) {
      int c = int(hue(palette[i])); 
      int distance = abs(c - int(hue(cible)));
      if (distance < proche) {
        proche = distance; 
        index = i;
      }
    }
    fill(0);
    ellipse(index * 20 + 90, 30, 10, 10); // pointeur
  } 
}


void couleurCible1(color c_) { // affichage de la couleur ciblé
  cible = c_;
  noStroke();
  fill(c_);
  rect(20, 20, 20, 20);
  
  r = color(0, 100, 100);
  
  if(cible == r); {
   //fill(0,100,100);
   rect( width/1.5, height/2.8, 150, 150);
     
  }

}

void couleurCible2(color c_) { // affichage de la couleur ciblé
  cible = c_;
  noStroke();
  fill(c_);
  rect(50, 20, 20, 20);
}

class Zone {
  //Déclaration des paramètres de base de la zone
  float x;
  float y;
  color couleur;

  //Constructeur de la zone
  Zone (float nouvX, float nouvY, color nouvCouleur) {
    x          = nouvX;
    y          = nouvY;
    couleur    = nouvCouleur;
  }

  //Dessin de la zone
  void display() {
    strokeWeight(2);
    stroke(0);
    noFill();
    rect(x, y, frameWidth,frameHeight);
  }
}

void structure() {  

  fill(255, 0, 255);
  rect(10, 71, 25, 24); // Z1 rect
  rect(10, 271, 25, 24); // Z2 rect
  noStroke();
  rect(10, 10, 200, 52); 
  rect(width/1.8, 0, width, height); // zone de dessin

  stroke(0);
  strokeWeight(1);
  rect(20, 20, 20, 20);
  rect(50, 20, 20, 20);
  fill(0);
  textSize(13);
  text("C1", 22, 57);
  text("C2", 52, 57);
  text("Z1", 15, 87);
  text("Z2", 15, 287);

  for (int i = 0; i < palette.length; i++) {  // dessin de la palette 
    noStroke();
    fill(palette[i]);
    rect(i * 20 + 80, 20, 20, 20);
  }
}


My problem occurs at this time.

void couleurCible1(color c_) { // affichage de la couleur ciblé
  cible = c_;
  noStroke();
  fill(c_);
  rect(20, 20, 20, 20);
  
  r = color(0, 100, 100);
  
  if(cible == r); {
   //fill(0,100,100);
   rect( width/1.5, height/2.8, 150, 150);

Any tips, or examples.
Thank you for your help.

1 Like

I am ignoring what structure(); is doing in this example.

Note that you need to use either video.available() in draw() or call the event handler captureEvent() so there is no need to call both.

I have seen a bit of repeated code here. So I deliberate simplified your code but it might not apply to your final design (or you can see if the modifications will work with your concept in mind).

I have added a field variable shape. Depending if the selected index in the palette is even or odd, it will draw the shape as rect or circ.

I have to use ellipseMode(CORNER) so ellipse can use the same parameter as used by rect(). Check the reference to learn more: ellipseMode and rectMode. My advise is that you define ellipseMode(CORNER) in setup and then you adapt your code to always use this mode. My personal preference is to use rectMode() in CENTER mode. If you were going to use this, you will need to change all your rect coordinate definitions. Something to consider at this stage. I find this mode is easier to handle object selection. At the end, it is your decision as any selection will work.

One thing: PFont was defined in setup once. No need to recreate (re-instantiate this object 30fps in draw().

Finally, frameWidth and frameHeight should not be global but should be member variables of Zone class. I leave it to you to implement this change.

Kf

import processing.video.*;

Capture video;
PImage scanArea;

color[] palette = {color(28, 5, 253), 
  color(100, 205, 205), 
  color(100, 100, 100), 
  color(250, 5, 40), 
  color(0, 255, 0), 
  color(255, 255, 0)};

//color red = color(0,100,100);
color r;

color cible;
int proche;
int index;

int frameWidth  = 200; // largeur de la zone de scan
int frameHeight = 200; // hauteur de la zone de scan

Zone maZone1 = new Zone(10, 71, color(255));
Zone maZone2 = new Zone(10, 271, color(255));


void setup() {
  size(640, 480);

  video = new Capture(this, width, height);
  video.start();

  colorMode(HSB, 360, 100, 100);
  noStroke();

  scanArea = createImage(frameWidth, frameHeight, RGB);
}

void captureEvent(Capture video) {
  video.read(); // Lecture de l'image provenant de la camera
}

void draw() {
  video.loadPixels();

  //if (video.available()) video.read(); // Update Capture

  pushMatrix();
  scale(-1, 1); // video en miroir 
  translate(-video.width, 0);
  image(video, 0, 0);
  popMatrix();


  if (frameCount % 50 == 0) { // Scan sans arret image par image 
    scanArea.copy(video, 200, 200, frameWidth, frameHeight, 0, 0, frameWidth, frameHeight);
  }

  proche = 360;
  index = 0;

  maZone1.display(); // affiche la zone de scan 1
  maZone2.display(); // affiche la zone de scan 2
  structure(); 

  maZone1.mouseHover();
  maZone2.mouseHover();

}

class Zone {
  //Déclaration des paramètres de base de la zone
  float x;
  float y;
  color couleur;
  int shape;

  //Constructeur de la zone
  Zone (float nouvX, float nouvY, color nouvCouleur) {
    x          = nouvX;
    y          = nouvY;
    couleur    = nouvCouleur;
    shape = 0;
  }

  //Dessin de la zone
  void display() {
    strokeWeight(2);
    stroke(0);
    noFill();
    rect(x, y, frameWidth, frameHeight);
  }

  void mouseHover() {
    if (mouseX > x && mouseX < x+frameWidth && mouseY > y && mouseY < y+frameHeight) { 
      couleurCible(get(mouseX, mouseY)); // couleur comparee, ciblée
      for (int i= 0; i < palette.length; i++) {
        int c = int(hue(palette[i])); 
        int distance = abs(c - int(hue(cible)));
        if (distance < proche) {
          proche = distance; 
          index = i;
          shape=i%2;
        }
      }
      fill(0);
      ellipse(index * 20 + 90, 30, 10, 10); // pointeur
    }
  }

  void couleurCible(color c_) { // affichage de la couleur ciblé
    cible = c_;
    noStroke();
    fill(c_);
    rect(20, 20, 20, 20);

    r = color(0, 100, 100);

    if (cible == r); 
    {
      pushStyle();    
      ellipseMode(CORNER);

      //fill(0,100,100);
      if (shape==0)
        rect( width/1.5, height/2.8, 150, 150);
      else
        ellipse( width/1.5, height/2.8, 150, 150);
      popStyle();
    }
  }
}

void structure() {  

  fill(255, 0, 255);
  rect(10, 71, 25, 24); // Z1 rect
  rect(10, 271, 25, 24); // Z2 rect
  noStroke();
  rect(10, 10, 200, 52); 
  rect(width/1.8, 0, width, height); // zone de dessin

  stroke(0);
  strokeWeight(1);
  rect(20, 20, 20, 20);
  rect(50, 20, 20, 20);
  fill(0);
  textSize(13);
  text("C1", 22, 57);
  text("C2", 52, 57);
  text("Z1", 15, 87);
  text("Z2", 15, 287);

  for (int i = 0; i < palette.length; i++) {  // dessin de la palette 
    noStroke();
    fill(palette[i]);
    rect(i * 20 + 80, 20, 20, 20);
  }
}

2 Likes

Thank you for your help!

With the code base you have rewritten, I was able to make my code more complex.
After that I can detect 8 colors on the basis of a color chart.

As for the structure(); it does not do anything special it just displays targets, areas and texts that come to take shape on top of the capture.

Indeed, I have a lot of repetition in my code including void colorCible1 (color c_) and void colorCible2 (color c_) which correspond to two separate zones.

I call the library OpenCV for the future because it’s a very good library for tracking contours and tracking color to!
I cleaned the code what did you think?

import gab.opencv.*;
import processing.video.*;

Capture video;
OpenCV opencv;

color cible;

color red;
color bleuc;
color bleuf;
color jaune; 
color vert;
color violet;
color rose;
color orange;

Zone maZone1 = new Zone(10, 71, color(255));
Zone maZone2 = new Zone(10, 271, color(255));


void setup() {

  video = new Capture(this, 640, 480);
  opencv = new OpenCV(this, video.width, video.height);

  size(1280, 480, P2D);

  colorMode(HSB, 360, 100, 100);

  video.start();
}


void draw() {

  background(255, 0, 255);

  video.loadPixels();

  if (video.available()) {
    video.read();
  }

  pushMatrix();
  scale(-1, 1); // video en miroir 
  translate(-video.width, 0);
  image(video, 0, 0);
  popMatrix();

  maZone1.display(); // affiche la zone de scan 1
  maZone2.display(); // affiche la zone de scan 2
  structure();  

  if (mouseX > 10 && mouseX < 210 && mouseY > 71 && mouseY < 275) { 
    couleurCible1(get(mouseX, mouseY)); // couleur comparee, ciblée
  }

  if (mouseX > 10 && mouseX < 210 && mouseY > 271 && mouseY < 492) { 
    couleurCible2(get(mouseX, mouseY)); // couleur comparee, ciblée
  }
}

void couleurCible1(color c_) { // affichage de la couleur ciblé

  cible = c_;
  noStroke();
  fill(c_);
  rect(20, 20, 20, 20);
  float value = hue(cible);

  red = color(0, 89, 89);
  bleuc = color(200, 89, 89);
  bleuf = color(244, 89, 89);
  jaune = color(56, 100, 100);
  vert = color(122, 60, 52);
  violet = color(290, 8, 53);
  rose = color(326, 89, 89);
  orange = color(19,89,89);

  if (value >= 0  && value <= 10) {  //ROUGE
    cible = red;
    noFill();
    strokeWeight(3);
    stroke(0, 100, 100); 
    ellipse(width/1.5, height/2.8, 100, 100);
  }

  if (value >= 170  && value <= 220) {  //BLEU CLAIRE
    cible = bleuc;
    noFill();
    strokeWeight(3);
    stroke(200, 100, 100); 
    ellipse(width/1.5, height/2.8, 100, 100);
  }
  
   if (value >= 230  && value <= 250) {  //BLEU FONCÉ
    cible = bleuf;
    noFill();
    strokeWeight(3);
    stroke(244, 100, 100); 
    ellipse(width/1.5, height/2.8, 100, 100);
  }

  if (value >= 50  && value <= 60) {  //JAUNE
    cible = jaune;
    noFill();
    strokeWeight(3);
    stroke(56, 100, 100); 
    ellipse(width/1.5, height/2.8, 100, 100);
  }

  if (value >= 70  && value <= 130) {  //VERT
    cible = vert;
    noFill();
    strokeWeight(3);
    stroke(122, 60, 52); 
    ellipse(width/1.5, height/2.8, 100, 100);
  }

  if (value >= 280  && value <= 300) {  //VIOLET
    cible = violet;
    noFill();
    strokeWeight(3);
    stroke(290, 81, 53); 
    ellipse(width/1.5, height/2.8, 100, 100);
  }
  
    if (value >= 340  && value <= 350) {  //ROSE
    cible = rose;
    noFill();
    strokeWeight(3);
    stroke(326, 89, 89); 
    ellipse(width/1.5, height/2.8, 100, 100);
  }
  
   if (value >= 10  && value <= 30) {  //ORANGE
    cible = orange;
    noFill();
    strokeWeight(3);
    stroke(19, 89, 89); 
    ellipse(width/1.5, height/2.8, 100, 100);
  }
  
}


void couleurCible2(color c_) { // affichage de la couleur ciblé
  cible = c_;
  noStroke();
  fill(c_);
  rect(50, 20, 20, 20);
}
class Zone {
  //Déclaration des paramètres de base de la zone
  float x;
  float y;
  color couleur;

  //Constructeur de la zone
  Zone (float nouvX, float nouvY, color nouvCouleur) {
    x          = nouvX;
    y          = nouvY;
    couleur    = nouvCouleur;
  }

  //Dessin de la zone
  void display() {
    strokeWeight(2);
    stroke(0);
    noFill();
    rect(x, y, 200, 200);
  }
}
void structure() {  

  fill(255, 0, 255);
  rect(10, 71, 25, 24); // Z1 rect
  rect(10, 271, 25, 24); // Z2 rect
  noStroke();
  rect(10, 10, 72, 52); 


  stroke(0);
  strokeWeight(1);
  rect(20, 20, 20, 20);
  rect(50, 20, 20, 20);
  fill(0);
  textSize(13);
  text("C1", 22, 57);
  text("C2", 52, 57);
  text("Z1", 15, 87);
  text("Z2", 15, 287);

}

That the color chart

I have another question about my code.

I need the detection of the color automatically faces in the defined areas zones: Area maZone1 = new Zone (10, 71, color (255)); and maZone2 = new Zone (10, 271, color (255)); without mouse x and mouse y by tracking and reading pixels.

So I took an example “Processing” BrightnessTracking and turned it into HueTracking.
Unfortunately I can not analyze the pixels, only in an DEFINED area of ​​the video.

/**
 * Brightness Tracking 
 * by Golan Levin. 
 *
 * Tracks the brightest pixel in a live video signal. 
 */


import processing.video.*;

Capture video;

//color trackColor;

void setup() {
  size(640, 480);
  // Uses the default video input, see the reference if this causes an error
  video = new Capture(this, width, height);
  video.start();  
  noStroke();
  smooth();
  
  //trackColor = color(255, 0, 0);
}

void draw() {
  if (video.available()) {
    video.read();
    colorMode(HSB, 360, 89, 89);
    image(video, 0, 0, width, height); // Draw the webcam video onto the screen
    int hueX = 0; // X-coordinate of the brightest video pixel
    int hueY = 0; // Y-coordinate of the brightest video pixel
    float hueValue = 0; // Hue of the Hue video pixel
    // Search for the brightest pixel: For each row of pixels in the video image and
    // for each pixel in the yth row, compute each pixel's index in the video
    video.loadPixels();
    int index = 0;
    for (int y = 0; y < video.height; y++) {
      for (int x = 0; x < video.width; x++) {
        // Get the color stored in the pixel
        int pixelValue = video.pixels[index];
        // Determine the brightness of the pixel
        float pixelHue = hue(pixelValue);
        // If that value is brighter than any previous, then store the
        // brightness of that pixel, as well as its (x,y) location
        if (pixelHue > hueValue) {
          hueValue = pixelHue;
          hueY = y;
          hueX = x;
        }
        index++;
      }
    }
    // Draw a large, yellow circle at the brightest pixel
    strokeWeight(3);
    stroke(0);
    noFill();
    ellipse(hueX, hueY, 50, 50);
  }
}

Do you have an idea of ​​the technique to use?
Thank you for your attention !!! :slight_smile:

1 Like

I do not understand. Can you explain more? What are you trying to do? Find the color(s) of each face? Faces are many colors – do you want the average color? Should that include hair?

1 Like

Excuse me for my english. I didn’t used the good word.

This program is a “card” reader. This is a game that will permite to create some graphic draws with colors cards.

When you put a map in the area, the program analyzes that area to detect the dominant color, (only in this area). When the program detects the color, it displays information related to that color.

for example : in zone 1 I put a red color card, in zone 2 I put a blue color card. So in the white drawing area will be display a red circle and a blue circle

I am looking for detected the color automatically in the area where the card is placed.
I show you a small video that illustrates the color detection of a potential color card.
For the moment detection is done with a mouse x mouse y (mouse pointer) but not automatically.

Is it clearer?

camille

1 Like

Maybe it’s more concret

Imagine all the card are a color and when the colors of all cards are detected a information are draw.

Imagine all the card have a color and when the colors of all cards are detected a information are draw.

other example :
informations

card red = fill(red)
card blue = circle
card yellow = x3

card red + card blue + card yellow = three greens circles

camille :slight_smile:

Update

finally I managed to analyse the pixels in an area, and calculate the average hue of the sums of all the pixels.

It works but I would like to detect a specific color (ex: yellow, red blue). Since he calculates an average of the sums of the pixels, he can not recognize an accurate color.

To recognize blue for example (in HSB mode)
I think I should:

  1. For each pixel, calculate whether the hue is between two values ​​(eg for blue between 200 and 250)
  2. IF the majority of pixels are between 200 and 250 THEN the average hue detected is blue.

tell me what you think?
and how could I do that?
any ideas?

import processing.video.*;

Capture video;
PImage scanArea;
float valeursNuances;
color cible;

color bluef ; 

void setup() {
  size(640, 480);
  colorMode(HSB, 360, 100, 100);
  video = new Capture(this, width, height);
  video.start();  
  noStroke();
  smooth();
  scanArea = createImage(100, 100, HSB); // Zone carré de 200 * 200
}

void draw() {

  if (video.available()) {
    video.read();
  }

  pushMatrix();
  scale(-1, 1); // Video en miroir 
  translate(-video.width, 0);
  image(video, 0, 0, width, height); // Dessin de la vidéo de la webcam sur l'écran
  scanArea.copy (video, 100, 100, 100, 100, 0, 0, 100, 100); // Copie d'une portion de l’image au même endroit ou elle se situe
  /*
  copy(src, sx, sy, sw, sh, dx, dy, dw, dh)
   src = video = Capture video
   sx,sy = 200,200 = coordonné de la zone à copier en x, y
   sw,sh = 200,200 = taille de la zone à copier en width, height
   dx,dy = 0,0 = coordonnée du coin supérieur gauche de la destination x, y
   dw,dh = 200,200 = taille de la zone copier en width, height
   */
  image(scanArea, 100, 100);
  noFill();
  stroke(56,100,100);
  rect(100, 100,100,100);
  popMatrix();

  scanArea.loadPixels(); // analyse de la zone 

  for (int i = 0; i < scanArea.pixels.length; i++) { // Calcul le nombre total de caractères inclus dans la chaîne
    color valeursBrutesPixels = scanArea.pixels[i]; // La valeur brutes des pixels est une moyenne de la zone scané 
    valeursNuances += hue(valeursBrutesPixels); // La couleur détectée est la teinte (°) de la valeur brutes des pixels
      
  }
  scanArea.updatePixels();

  valeursNuances = (float) valeursNuances / (100 * 100); //  Calcul de la moyenne pour la couleur détectée  
  println(valeursNuances);

  bluef = color(244, 89, 89);

  strokeWeight(2);
  stroke(56,100,100);
  noFill();
  ellipse(100, 150, 50, 50);

  if (valeursNuances >= 200  && valeursNuances <= 250) { 
    fill(bluef);
    ellipse(100, 150, 50, 50);
  }

}


Camille

1 Like

While you can walk through the hues yourself, you might want to consider using the OpenCV library and inRange to track / detect an object of a specific hue range:

see also:

2 Likes

Hey !!

Sure, In the end I should use this library !!!
But for the moment I try without her, because I try to create scanArea (traking zone).
But I have a problème!

I managed to detected the color automatically in a scanArea where the card is placed. (CodeV_1)
And actually I try to create 4 scanArea with an Array to simplify the code.
But my problem is that I can’t tell to my program to analyse each “scanArea” for display on the drawing area the color that corresponds

The program don’t understand this part :
CodeV_2

void zone1() {

  for (int i = 0; i < scanArea.length; i++) {
    scanArea[i].loadPixels();
    //scanloadPixels();

    if (CameraActive == true) {
      int index = 0;

      for (int j = 0; j < scanArea[i].pixels.length; j++) {
        int pixelValue = scanArea[i].pixels[index];
        float pixelHue = hue(pixelValue);

And on particularly for (int i = 0; i < scanArea.length; i++) { scanArea[i].loadPixels();

Here is the complete code
CodeV_2

import processing.video.*;

Capture video;

boolean CameraActive = false;
boolean Cameralu = false;
boolean effacer = false;
boolean violet = false;
boolean rouge = false;
boolean vert = false;

PImage [] scanArea = new PImage[4];


int frameWidth  = 640; // largeur de la video
int frameHeight = 480; // hauteur de la video

void setup() {

  size(1080, 480);
  frameRate(24);
  colorMode(HSB, 360, 100, 100);
  video = new Capture(this, frameWidth, frameHeight);
  video.start();  
  //smooth(0);

  for (int i = 0; i < scanArea.length; i++) {
    scanArea[i] = createImage(frameWidth/4-10, frameHeight/3, HSB); //ok
  }
}
void draw() {

  if (video.available()) {
    video.read();

    image(video, 0, 0, frameWidth, frameHeight); // Dessin de la vidéo de la webcam sur l'écran

    scanArea[0].copy(video, 20, frameHeight/3, frameWidth/4-10, frameHeight/3, 20, frameHeight/3, frameWidth/4-10, frameHeight/3); 
    scanArea[1].copy(video, frameWidth/4+10, frameHeight/3, frameWidth/4-10, frameHeight/3, frameWidth/4+10, frameHeight/3, frameWidth/4-10, frameHeight/3);
    scanArea[2].copy(video, 2*frameWidth/4, frameHeight/3, frameWidth/4-10, frameHeight/3, 2*frameWidth/4, frameHeight/3, frameWidth/4-10, frameHeight/3); 
    scanArea[3].copy(video, 3*frameWidth/4-10, frameHeight/3, frameWidth/4-10, frameHeight/3, 3*frameWidth/4-10, frameHeight/3, frameWidth/4-10, frameHeight/3); 

    image(scanArea[0], 20, frameHeight/3);
    image(scanArea[1], frameWidth/4+10, frameHeight/3);
    image(scanArea[2], 2*frameWidth/4, frameHeight/3);
    image(scanArea[3], 3*frameWidth/4-10, frameHeight/3);

    structure(); 
    zone1();
  }
}

void zone1() {

  for (int i = 0; i < scanArea.length; i++) {
    scanArea[i].loadPixels();
    //scanloadPixels();

    if (CameraActive == true) {
      int index = 0;

      for (int j = 0; j < scanArea[i].pixels.length; j++) {
        int pixelValue = scanArea[i].pixels[index];
        float pixelHue = hue(pixelValue);

        if (pixelHue<300 && pixelHue>280) {
          violet = true;
          println(scanArea[i], "violet");
        }
        if (pixelHue<360 && pixelHue>300) {
          rouge = true;
          println(scanArea[i], "rouge");
        }
        if (pixelHue<100 && pixelHue>80) {
          vert = true;
          println(scanArea[i], "vert");
        } 
        index++;
      }
    }

    if (Cameralu == true) {
      if (rouge == true) {
        //noStroke();
        fill(360, 100, 100);
        ellipse(2*width/3, height/2.8, 100, 100);
        violet = false;
        vert = false;
      }
      if (violet == true) {
        //noStroke();
        fill(280, 100, 100);
        ellipse(2*width/3, height/2.5, 100, 100);
        rouge = false;
        vert = false;
      }
      if (vert == true) {
        //noStroke();
        fill(80, 100, 100);
        ellipse(2*width/3, height/2, 80, 80);
        rouge = false;
        violet = false;
      }
      if (effacer == true) {
        noStroke();
        fill(0);
        rect(640, 0, 440, 480);
      }
    }
  }
}

void structure() {  


  fill(0);    
  noStroke();
  rect(640, 0, 440, 480);

  textSize(13);
  fill(60, 100, 100);
  text("Z1", 23, frameHeight/3+15); 
  text("Z2", 1*frameWidth/4+13, frameHeight/3+15); 
  text("Z3", 2*frameWidth/4+3, frameHeight/3+15); 
  text("Z4", 3*frameWidth/4-7, frameHeight/3+15);

  strokeWeight(2);
  stroke(60, 100, 100);
  noFill();
  rect(20, frameHeight/3, frameWidth-40, frameHeight/3);
  line(frameWidth/4+10, frameHeight/3, frameWidth/4+10, 2*frameHeight/3);
  line(2*frameWidth/4, frameHeight/3, 2*frameWidth/4, 2*frameHeight/3);
  line(3*frameWidth/4-10, frameHeight/3, 3*frameWidth/4-10, 2*frameHeight/3);

  rect(20, 2*frameHeight/3+50, 30, 30);
  rect(1*frameWidth/4+10, 2*frameHeight/3+50, 30, 30);
  rect(2*frameWidth/4, 2*frameHeight/3+50, 30, 30);
  rect(3*frameWidth/4-10, 2*frameHeight/3+50, 30, 30);


  /*fill(0, 100, 100);
   rect(20, frameHeight/3, frameWidth/4-10, frameHeight/3); // sanArea1 si mirroir scanArea4
   rect(1*frameWidth/4+10, frameHeight/3, frameWidth/4-10, frameHeight/3); // sanAre2 si mirroir scanArea3
   rect(2*frameWidth/4, frameHeight/3, frameWidth/4-10, frameHeight/3); // sanArea3 si mirroir scanArea2
   rect(3*frameWidth/4-10, frameHeight/3, frameWidth/4-10, frameHeight/3); // sanArea4 si mirroir scanArea1*/
}

void keyPressed() {
  if (key == 'a') {
    CameraActive = true; 
    Cameralu = true;
    effacer = false;
  }
  if (key == 'b') {
    effacer = true;
    rouge = false;
    violet = false;
    vert = false;
  }
}
void keyReleased() {
  if (key == 'a') {
    CameraActive = false;
  }
}

CodeV_1

import processing.video.*;

Capture video;

boolean CameraActive = false;
boolean Cameralu = false;
boolean effacer = false;
boolean violet = false;
boolean rouge = false;
boolean vert = false;

PImage scanArea;

int frameWidth  = 640; // largeur de la video
int frameHeight = 480; // hauteur de la video

void setup() {
  size(1080, 480);
  frameRate(24);
  colorMode(HSB, 360, 100, 100);
  video = new Capture(this, frameWidth, frameHeight);
  video.start();  
  noStroke();
  //smooth(0);
  scanArea = createImage(100, 100, HSB);
}
void draw() {
  background(0);
  if (video.available()) {
    video.read();
    image(video, 0, 0, frameWidth, frameHeight); // Draw the webcam video onto the screen
    scanArea.copy (video, 0, 0, 100, 100, 0, 0, 100, 100); // Copie d'une portion de l’image au même endroit ou elle se situe
    image(scanArea, 0, 0);
    strokeWeight(1);
    stroke(0);
    noFill();
    rect(0, 0, 100, 100);
    zone1();
  }
}
void zone1() {
  scanArea.loadPixels();
  if (CameraActive == true) {
    int index = 0;
    for (int i = 0; i < scanArea.pixels.length; i++) {
      int pixelValue = scanArea.pixels[index];
      float pixelHue = hue(pixelValue);
      
      if (pixelHue<300 && pixelHue>280) {
        violet = true;
        println("violet");
      }
      if (pixelHue<360 && pixelHue>300) {
        rouge = true;
        println("rouge");
      }
      if (pixelHue<100 && pixelHue>80) {
        vert = true;
        println("vert");
      } 
      index++;
    }
  }
    if (Cameralu == true) {
      if (rouge == true) {
        // stroke(0);
        fill(360, 100, 100);
        ellipse(2*width/3, height/2.8, 100, 100);
        violet = false;
        vert = false;
      }
      if (violet == true) {
        //stroke(0);
        fill(280, 100, 100);
        ellipse(2*width/3, height/2.5, 100, 100);
        rouge = false;
        vert = false;
      }
      if (vert == true) {
        //stroke(0);
        fill(80, 100, 100);
        ellipse(2*width/3, height/2, 80, 80);
        rouge = false;
        violet = false;
      }
      if (effacer == true) {
        fill(0);
        rect(640, 0, 440, 480);
      }
    }
  }
void keyPressed() {
  if (key == 'a') {
    CameraActive = true; 
    Cameralu = true;
    effacer = false;
  }
  if (key == 'b') {
    effacer = true;
    rouge = false;
    violet = false;
    vert = false;
  }
}
void keyReleased() {
  if (key == 'a') {
    CameraActive = false;
  }
}

Thank you for your attention :pray:

Camille.

1 Like

What error message(s) are you getting?

For for (int i = 0; i < scanArea.length; i++) { scanArea[i].loadPixels();

“Cannot invoke loadPixels() on the array type PImage”

That doesn’t look right.

That is an error that should happen if you write scanArea.loadPixels() (WRONG) instead of scanArea[i].loadPixels() (RIGHT).

But your v2 code doesn’t have that error. When I run your v2 code, it runs with no errors.

1 Like

Yes indeed, but I deduced that it did not work because my “keyPressed” and “keyReleased” function does not work anymore …
I have no “println()” that appears in the information bar

Please be more clear. You said you were getting the “Cannot invoke” error message from your code. I said: I am not getting that error. You said “yes indeed.” ??

So: are you getting an error, or are you not getting an error? With what code, specifically? Please be more clear so that we can help you.

1 Like

I’m sorry I’m not fluent in english so I’m trying to explain the most clearly possible.

For this : I want to say yes my code run without errors.

Please be more clear. You said you were getting the “Cannot invoke” error message from your code. I said: I am not getting that error. You said “yes indeed.” ??

My CodeV_2 run without error but my function “KeyPressed / keyReleased” does not work because the code does not do what I would like. Unlike CodeV_1 which has the function “keyPressed / keyReleased” that works.

I explain you :
The difference between the two codes is that in CodeV_1 there is only one “scanArea” to analyze.

  • When I press “a” the scanArea is analyse / a color is detected and a color form is draw.

And in CodeV_2 there are 4 “scanArea” to analyze.

  • When I press “a”, I have nothing in the information bar and nothing in the drawing zone. I have the impression that he did not find color, or that the scanArea are not analyzed.

I hadn’t this error : “Cannot invoke loadPixels() on the array type PImage” with the the CodeV_2, sorry for the confusion. You can forgot this error message, sorry.

It’s more clear ? :blush:

Camille.