4.5 Color Tracking + Physics

Open Cv color detection: https://www.codersarts.com/post/determine-color-contours-and-center-using-opencv

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

ArrayList <PVector> pixelmatch = new ArrayList <PVector>();
ArrayList <FPoly> rigid = new ArrayList <FPoly> ();
ArrayList <FCircle> circles = new ArrayList <FCircle> ();

Capture cam;

PGraphics video_holder;

FWorld world;

PImage src, dst;
OpenCV opencv;

float ct = 0;
float ctlimit = 25;

ArrayList<Contour> contours;
ArrayList<Contour> polygons;

// <1> Set the range of Hue values for our filter
int rangeLow = 0;
int rangeHigh = 0;

PImage  colorFilteredImage;

void setup() {
  size(1280, 480);
  
  video_holder = createGraphics(width,height);
  
  String[] cameras = Capture.list();


  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++) { 
     println(cameras[i]); 
    } 
    // The camera can be initialized directly using an 
    // element from the array returned by list(): 
    cam = new Capture(this, cameras[1]); 
    cam.start(); 
  } 

 Fisica.init(this); 
 world = new FWorld(); 
 world.setGravity(0, 100); 
} 

void draw() { 
 background(0); 
 if (cam.available() == true) { 
  cam.read(); 
 } 
 video_holder.beginDraw(); 
 video_holder.image(cam, 0, 0); 
 video_holder.endDraw(); 
 image(video_holder,0,0);  

 if(ct > ctlimit){
    ct = 0;
    ctlimit = random(15) + 15;
    float sz = random(10,40); 
    FCircle b = new FCircle(sz); 
    b.setPosition(random(width), -40); 
    b.setVelocity(0, -40); 
    b.setRestitution(0.7); 
    b.setDamping(0.01); 
    b.setNoStroke(); 
    b.setFill(random(255), random(255), random(255)); 
    circles.add(b);
    world.add(b); 
  }
  ct++;
  
  opencv = new OpenCV(this,cam);
  
  // Tell OpenCV to use color information
  opencv.useColor();
  src = opencv.getSnapshot();
  
  // <3> Tell OpenCV to work in HSV color space.
  opencv.useColor(HSB);
  
  // <4> Copy the Hue channel of our image into 
  //     the gray channel, which we process.
  opencv.setGray(opencv.getH().clone());
  
  // <5> Filter the image based on the range of 
  //     hue values that match the object we want to track.
  opencv.inRange(rangeLow, rangeHigh);
  contours = opencv.findContours();
  // <6> Get the processed image for reference.
  colorFilteredImage = opencv.getSnapshot();
  
  
  image(colorFilteredImage,src.width,0);
  
  noFill();
  strokeWeight(3);
  
  for (Contour contour : contours) {
    stroke(0, 255, 0);
    contour.draw();
    
    stroke(255, 0, 0);
    float a = contour.area();
    if(a > 20 && a < (width-70) * (height - 70)){
      int c = 0;
 
      FPoly p = new FPoly();
      p.setFill(120, 30, 90,0);
      p.setNoStroke();
      p.setRestitution(0);
      p.setStatic(true);
      
      contour.setPolygonApproximationFactor(6);
      for (PVector point : contour.getPolygonApproximation().getPoints()) {
        p.vertex(point.x, point.y);
        c++;
      }
      world.add(p);
      rigid.add(p);
    }
  }
  
  world.draw();
  world.step();
  
  for(int i = 0; i < rigid.size(); i++){ 
    FPoly b = rigid.get(i); 
    world.remove(b); 
  } 
  
  for(int i = 0; i < circles.size(); i++){ FCircle c = circles.get(i); if(c.getY() > height + 50){
      world.remove(c); 
    }
  } 
  
  
  println("F " + frameRate);
}


void keyPressed() { 
  if( key == ' ' ){
    float sz = random(20,50); 
    FCircle b = new FCircle(sz); 
    b.setPosition(random(30,src.width-30), 0); 
    b.setVelocity(random(-100,100), -40); 
    b.setRestitution(0.7); 
    b.setDamping(0.01); 
    b.setNoStroke(); 
    b.setFill(random(255), random(255), random(255)); 
    world.add(b); 
  }
} 

void contactEnded(FContact c) { 
  if (!c.getBody1().isStatic()) { 
    FCircle b = (FCircle)c.getBody1(); 
    if (b.getSize()>12) {
      b.setSize(b.getSize()*0.99);
    }
  } 

  if (!c.getBody2().isStatic()) {
    FCircle b = (FCircle)c.getBody2();
    if (b.getSize()>12) {
      b.setSize(b.getSize()*0.99);
    }
  }
}

void mousePressed() {
  
  color c = get(mouseX, mouseY);
  println("r: " + red(c) + " g: " + green(c) + " b: " + blue(c));
   
  int hue = int(map(hue(c), 0, 255, 0, 180));
  println("hue to detect: " + hue);
  
  rangeLow = hue - 1;
  rangeHigh = hue + 1;
}