ԀI˥ℲOᙠᴚ∩⊥
🔍

Webcam as visual sensor

low res facetted webcam feed

using the webcam as a low res facetted brightness input device

let gsx = 32;
let gsy = 24;

let xscl = 1;
let yscl = 1;

let video;

function setup() {
  createCanvas(window.innerWidth, window.innerHeight);
   
   xscl = width/gsx;
   yscl = height/gsy;
  
  video = createCapture(VIDEO);
  video.size(gsx,gsy);
  video.hide();
  noSmooth();
   
}

function draw(){
 
  background(222);
  video.loadPixels();
  noStroke();  
   
  for( let x=0; x< gsx; x++){
    
      for( let y=0; y< gsy; y++){
  
          var index = (video.width - x -1 + (y * video.width)) * 4;
          var r = video.pixels[index + 0];
          var g = video.pixels[index + 1];
          var b = video.pixels[index + 2];
          var bri = (r + g + b) / 3;
        
         let xpos = x*xscl; 
         let ypos = y*yscl; 
        
         fill(bri);
         rect(xpos,ypos, xscl, yscl);
        
      }
  }
}

smooth blob detection

pixel difference operation – aka low tech motion detection with a smoothed centered blob

let gsx = 32;
let gsy = 24;

let xscl = 1;
let yscl = 1;

let video;
let pmtx = [];

// motion detection vars
let motion_threshold = 30;
let motion_center_x = 0;
let motion_center_y = 0;

let target_x = 0;
let target_y = 0;

let smooth_x = 0;
let smooth_y = 0;

function setup() {
  createCanvas(window.innerWidth, window.innerHeight);

  xscl = width / gsx;
  yscl = height / gsy;

  video = createCapture(VIDEO);
  video.size(gsx, gsy);
  video.hide();
  noSmooth();
}

function draw() {
  let thres_ticker = 0; // ticker for square sum of diff pixels
  motion_center_x = 0; // reset center
  motion_center_y = 0;

  background(111);

  video.loadPixels();

  noStroke();

  for (let x = 0; x < gsx; x++) {
    for (let y = 0; y < gsy; y++) {
      var index = (video.width - x - 1 + y * video.width) * 4;
      var r = video.pixels[index + 0];
      var g = video.pixels[index + 1];
      var b = video.pixels[index + 2];
      var bri = (r + g + b) / 3;

      let xpos = x * xscl;
      let ypos = y * yscl;

      let diff = pmtx[index] - bri;

      if (diff > motion_threshold) {
        fill(diff * 3);
        motion_center_x += xpos;
        motion_center_y += ypos;
        thres_ticker++;
      } else {
        fill(0);
      }

      rect(xpos, ypos, xscl - 1, yscl - 1);
      pmtx[index] = bri;
    }
  }

  if (thres_ticker > 0) {
    // draw motion center blob
    target_x = motion_center_x / thres_ticker;
    target_y = motion_center_y / thres_ticker;
  }

  smooth_x = lerp(smooth_x, target_x, 0.02);
  smooth_y = lerp(smooth_y, target_y, 0.02);

  fill(22, 22, 222);
  ellipse(smooth_x, smooth_y, 42, 42);
}

motion detection / heatmap buffer method

basic heatmap motion detection – all pixel difference is stored in buffer array to be visualized

let gsx = 128;
let gsy = 96;

let xscl = 1;
let yscl = 1;

let video;
let pmtx = [];

// motion detection vars
let motion_threshold = 30;
let motion_center_x = 0;
let motion_center_y = 0;

let target_x = 0;
let target_y = 0;

let smooth_x = 0;
let smooth_y = 0;

let heatmap; // heatmap image
let heatmap_data = [];

function setup() {
  createCanvas(window.innerWidth, window.innerHeight);

  heatmap = createGraphics(gsx, gsy); // 32 x 24
  heatmap_data = new Array(gsx * gsy); 
  init_heatmap_data();
  
  pmtx = new Array(gsx * gsy);

  xscl = width / gsx;
  yscl = height / gsy;

  video = createCapture(VIDEO);
  video.size(gsx, gsy);
  video.hide();
  
}

function draw() {
  let thres_ticker = 0; // ticker for square sum of diff pixels
  motion_center_x = 0; // reset center
  motion_center_y = 0;

 //& draw_heatmap_data();
 
  render_heatmap();
 
  
  video.loadPixels();

  noStroke();

  for (let x = 0; x < gsx; x++) {
    for (let y = 0; y < gsy; y++) {
      
      var index = (video.width - x - 1 + y * video.width) * 4;
      var i = int(index/4);
      var r = video.pixels[index + 0];
      var g = video.pixels[index + 1];
      var b = video.pixels[index + 2];
      var bri = (r + g + b) / 3;

      let xpos = x * xscl;
      let ypos = y * yscl;

      let diff = pmtx[i] - bri;

      if (diff > motion_threshold) {
        
        if(diff!=null){
         heatmap_data[i] += int(diff)*2.;
        }
          fill(diff * 13);
        motion_center_x += xpos;
        motion_center_y += ypos;
        thres_ticker++;
      } else {
        fill(0);
        
      }

      heatmap_data[i] *= 0.97;
      //ellipse(xpos+xscl/2, ypos+yscl/2, xscl*.3, xscl*.3);
      pmtx[i] = bri;
    }
  }

  if (thres_ticker > 0) {
    // draw motion center blob
    target_x = motion_center_x / thres_ticker;
    target_y = motion_center_y / thres_ticker;
  }

  smooth_x = lerp(smooth_x, target_x, 0.02);
  smooth_y = lerp(smooth_y, target_y, 0.02);

  
  
  
}
function render_heatmap() {
  
  heatmap.loadPixels();
 
  for (let i = 0; i < heatmap_data.length*4; i += 4) {
    let ireal = int(i/4); 
    heatmap.pixels[i] = heatmap_data[ireal];
    heatmap.pixels[i + 1] = heatmap_data[ireal];
    heatmap.pixels[i + 2] = heatmap_data[ireal];
    heatmap.pixels[i + 3] = 155; 
  }

  heatmap.updatePixels();
  //heatmap.smooth(2);
   image(heatmap,0,0,width,height);
  
}

function init_heatmap_data(){
  
  
   for (let i = 0; i < heatmap_data.length; i++) {
     
     heatmap_data[i] = 1;
   }
  
  for (let i = 0; i < pmtx.length; i++) {
     
      pmtx[i] = 1;
   }
  
  
}


todo – implement voxel 3D with shader > https://www.shadertoy.com/view/NtfXWS

Related Posts
SPEAK WITH AN 8-BIT COMPUTER
SPEAK WITH AN 8-BIT COMPUTER

microphone input is observed to trigger random 8-bit sound

SPEECH IN : SPEECH OUT
SPEECH IN : SPEECH OUT

realtime speech recorgnisiton and speech synthesis in the browser

THE WANDERING BRUSH
THE WANDERING BRUSH

simple drawing machine introducing classes and objects

GAMEPAD BROWSER INPUT
GAMEPAD BROWSER INPUT

how to grab data input from Bluetooth gamepad to browser with JS