Sélecteur de couleur / Processing + Android


Programme de traitement sélectif de l'image d'une caméra de smartphone ou tablette Android.
Sélection de la couleur au touché et suivi en temps réel.Le traitement débute au lancement de la caméra. La plage de sélection s'effectue grâce à un ascenseur de seuil et le menu permet de permuter entre caméra frontal et arrière et d'utiliser le flash.
L'interface affiche un retour sur le pourcentage de pixels colorés sélectionnés.

Source: detectorColorProcessingAndroid.pde / Processing 3.5.3 + Android mode + librairie Ketai

import ketai.camera.*;
KetaiCamera camD;

PGraphics container;
PImage camImage;

boolean onFrontCam, switchCam;
int camWidth, camHeight;
int pixelColorX, pixelColorY;

boolean trackingPixelColor, tresholdColorCursor;
color targetColor;
int colorTreshold;
int pixelTreshold;
PVector tresholdCursor = new PVector(0,0);

int nbTotalPixels;
float nbMaxPixels;
float nbMinPixels;
float nbPixels;
float pourcent;

int startTimer;
int timerSwitchCam;
int refresh;
int refreshSwitchCam;

String texte1 = "";
String texte2 = "";
int textSize;

int UITop, UIBottom, UIRight;

void setup(){
  fullScreen();
  orientation(LANDSCAPE);
  imageMode(CENTER);
  frameRate(30);
  
  camWidth = 1280;
  camHeight = 720;
  camD = new KetaiCamera(this, camWidth, camHeight, 24);
  camD.setCameraID(0);

  rectMode(CORNER);
  imageMode(CORNER);

  onFrontCam = false;
  switchCam = true;
  trackingPixelColor = false;
  
  colorTreshold = 40;
  targetColor = color(255, 153, 0); // color(190, 130, 70);
  textSize = 40;
  textSize(textSize);
  fill(targetColor);
  UIBottom = textSize*3;
  UITop = textSize+40;
  UIRight = textSize*2;
  
  nbTotalPixels = camWidth*camHeight;
  pixelTreshold = 1; // seuil en pixels de traitement de la video
  nbMaxPixels = nbTotalPixels*0.6; // pourcentage max: 60%
  nbMinPixels = nbTotalPixels*0.2; // pourcentage min: 20%
  
  refresh = 5000; // delai photo nbPixels > nbMaxPixels
  refreshSwitchCam = 10000;
  timerSwitchCam = millis() + refreshSwitchCam;
  startTimer = millis() + refresh;
}

void timerCamRefresh(){
  timerSwitchCam = millis() + refreshSwitchCam;
}

void draw(){
  background(0);

  if (camD != null) {
    texte1 = "< ... >";
    
    if(trackingPixelColor){
      pixelColorX = int(map(mouseX, 0, width, 0, camWidth));
      pixelColorY = int(map(mouseY, 0, height, 0, camHeight));
      camD.loadPixels();
      targetColor = camD.get(pixelColorX, pixelColorY);
      fill(targetColor);
      
      image(camD, 0, 0, width, height);
      texte2="<SearchColor> <R: " + red(targetColor) + " / G: " + green(targetColor) + " / B: " + blue(targetColor) + ">";
      rect(0, UITop, 100, 100);
    }else{
      texte2="<SearchPixels><tresholdColor: " + colorTreshold + "><" + nbPixels + " / " + nbTotalPixels + "> <" + pourcent*100 + "%>";
      
      nbPixels = 0;
      camD.loadPixels();
      container = createGraphics(camWidth, camHeight);
      container.beginDraw();
      container.noStroke();
      
      
      for (int y = 0; y < camHeight-pixelTreshold; y=y+pixelTreshold) {
        for (int x = 0; x < camWidth-pixelTreshold; x=x+pixelTreshold) {
          color pixelColor = camD.get(x, y);        
  
          if (red(pixelColor) > red(targetColor)-colorTreshold && red(pixelColor) < red(targetColor)+colorTreshold &&
            green(pixelColor) > green(targetColor)-colorTreshold && green(pixelColor) < green(targetColor)+colorTreshold &&
            blue(pixelColor) > blue(targetColor)-colorTreshold && blue(pixelColor) <blue(targetColor)+colorTreshold) {
            
            nbPixels += pixelTreshold*pixelTreshold;
              
            container.fill(targetColor);  
            container.rect(x-pixelTreshold, y-pixelTreshold, pixelTreshold*2, pixelTreshold*2);
          }
        }
      }
      
      pourcent = nbPixels/nbTotalPixels;  
      if(pourcent > 0.1){
        texte1="<colorDetected>";
      }else{
        texte1="<...>";
      }
      
      container.endDraw();
      image(camD, 0, 0, width, height);
      image(container, 0, 0, width, height);
    }
  }
  drawUI();
}


void onCameraPreviewEvent() {
  camD.read();
}

void mousePressed(){
  //touch screen color selection
  if(mouseY > UITop && mouseY < height - UIBottom && mouseX < width - UIRight){
    trackingPixelColor = true;
  }else{
    trackingPixelColor = false;
  }
  
  //cursor color treshold
  if(mouseX > width-UIRight && mouseY > UITop && mouseY < height-(UITop + UIBottom)){
    tresholdColorCursor = true;
  }else{
    tresholdColorCursor = false;
  }
  
  //menu 1
  if (mouseX < width/5 && mouseY < 40){
    if (camD.isStarted()){
      camD.stop();
    }else{
      camD.start();
    }
  }
  
  //menu 2
  if (mouseX < 2*width/5 && mouseX > width/5 && mouseY < 40){
    if (camD.getNumberOfCameras() > 1){
      camD.setCameraID((camD.getCameraID() + 1 ) % camD.getNumberOfCameras());
    }
  }
  
  //menu 3
  if(mouseX > 2*width/5 && mouseX < 3*width/5 && mouseY < 40){
    if (camD.isFlashEnabled()){
      camD.disableFlash();
    }else{
      camD.enableFlash();
    }
  }
  
  //menu 4
  if(mouseX > 3*width/5 && mouseX < 4*width/5 && mouseY < 40){
    
  }
  
  //menu 5
  if(mouseX > 4*width/5 && mouseY < 40){
    
  }
}

void mouseReleased(){
  if(trackingPixelColor){
    trackingPixelColor = false;
  }
}

void drawUI()
{
  pushStyle();
  textAlign(CENTER);
  int textSpace = width/10;
  fill(0);
  rect(0, 0, width, UITop);

  fill(200);
  text("|", 2*textSpace,  3*UITop/4);
  text("|", 4*textSpace,  3*UITop/4);
  text("|", 6*textSpace,  3*UITop/4);
  text("|", 8*textSpace,  3*UITop/4);
  if (camD.isStarted()){
    text("Camera Off", textSpace, 3*UITop/4); 
  }else{
    text("Camera On", textSpace, 3*UITop/4);
  }

  if (camD.getNumberOfCameras() > 0){
    text("Switch Camera", 3*textSpace, 3*UITop/4);
  }

  if (camD.isFlashEnabled()){
    text("Flash Off", 5*textSpace, 3*UITop/4); 
  }else{
      text("Flash On", 5*textSpace, 3*UITop/4);
  }
  
  // treshold cursor
  fill(0);
  rect(width-UIRight, UITop, UIRight, height-(UITop + UIBottom));
  tresholdCursor.x = width-UIRight;
  if(tresholdColorCursor){
    tresholdCursor.y = mouseY;
    colorTreshold = int(map(tresholdCursor.y, UITop, height-(UITop + UIBottom), 0, 100));
  }else{
    tresholdCursor.y = int(map(colorTreshold, 0, 100, UITop, height-(UITop + UIBottom)));
  }
  fill(200);
  rect(tresholdCursor.x, tresholdCursor.y, UIRight, UIRight);
  
  //Infos
  fill(0);
  rect(0, height-UIBottom, width, UIBottom);
  fill(200);
  rect(0, height-UIBottom, width*pourcent, 30);
  textAlign(CORNER);
  text(texte1, 27, height-textSize);
  text(texte2, 27, height);
  popStyle();
}

Laisser un commentaire