xxxxxxxxxx
168
// https://inspirit.github.io/jsfeat/sample_oflow_lk.html
var cnv;
var capture;
var curpyr, prevpyr, pointCount, pointStatus, prevxy, curxy;
var w = 640,
h = 480;
var maxPoints = 1000;
//Michael: Array for storing point moving status
//And variable storing how many moving points.
let pointsMoving = [];
let oscs = [];
let stillPoints;
function setup() {
//Michael: I had to lower the framerate to make it silent while dots are moving
frameRate(60);
capture = createCapture(
{
audio: false,
video: {
width: w,
height: h,
},
},
function () {
console.log("capture ready.");
}
);
capture.elt.setAttribute("playsinline", "");
cnv = createCanvas(w, h);
capture.size(w, h);
capture.hide();
//Michael: counting not moving points.
stillPoints = 0;
curpyr = new jsfeat.pyramid_t(3);
prevpyr = new jsfeat.pyramid_t(3);
curpyr.allocate(w, h, jsfeat.U8C1_t);
prevpyr.allocate(w, h, jsfeat.U8C1_t);
pointCount = 0;
pointStatus = new Uint8Array(maxPoints);
prevxy = new Float32Array(maxPoints * 2);
curxy = new Float32Array(maxPoints * 2);
}
//Michael: I dont think we need this
// function keyPressed(key) {
// for (var i = 0; i < 100; i++) {
// addPoint(random(width), random(height));
// }
// }
//Michael: We would click on color spot on robot at the beginning
function mousePressed() {
addPoint(mouseX, mouseY);
}
function addPoint(x, y) {
if (pointCount < maxPoints) {
pointsMoving[pointCount] = false;
//Michael: Creating Osc for each point.
oscs[pointCount] = new p5.Oscillator("sine");
oscs[pointCount].amp(0,0.1);
oscs[pointCount].start();
var pointIndex = pointCount * 2;
curxy[pointIndex] = x;
curxy[pointIndex + 1] = y;
pointCount++;
}
}
function prunePoints() {
var outputPoint = 0;
for (var inputPoint = 0; inputPoint < pointCount; inputPoint++) {
if (pointStatus[inputPoint] == 1) {
if (outputPoint < inputPoint) {
var inputIndex = inputPoint * 2;
var outputIndex = outputPoint * 2;
curxy[outputIndex] = curxy[inputIndex];
curxy[outputIndex + 1] = curxy[inputIndex + 1];
}
outputPoint++;
}
}
pointCount = outputPoint;
}
function draw() {
image(capture, 0, 0, w, h);
push();
noFill();
stroke(255);
ellipse(width/2,height/2,height);
pop();
capture.loadPixels();
if (capture.pixels.length > 0) { // don't forget this!
var xyswap = prevxy;
prevxy = curxy;
curxy = xyswap;
var pyrswap = prevpyr;
prevpyr = curpyr;
curpyr = pyrswap;
// these are options worth breaking out and exploring
var winSize = 30;
var maxIterations = 30;
var epsilon = 0.05;
var minEigen = 0.001;
jsfeat.imgproc.grayscale(capture.pixels, w, h, curpyr.data[0]);
curpyr.build(curpyr.data[0], true);
jsfeat.optical_flow_lk.track(
prevpyr,
curpyr,
prevxy,
curxy,
pointCount,
winSize,
maxIterations,
pointStatus,
epsilon,
minEigen
);
prunePoints();
if(frameCount% 30 ==0){
for (var i = 0; i < pointCount; i++) {
//Michael: Cal distance to the center of the circle
let pointDistToCtr = dist(curxy[i], curxy[i + 1],width/2,height/2);
let pointMappedFreq = map(pointDistToCtr,0,height/2, 440,880);
oscs[i].freq(pointMappedFreq, 0.1);
//Michael: Cal current and previous point difference.
//0.5 is how senstive it should be
//I then store the pooint status - morving or not - in an array
let prevcurDiff = dist(prevxy[i], prevxy[i + 1], curxy[i], curxy[i + 1]);
console.log(prevcurDiff);
if (prevcurDiff > 1) {
pointsMoving[i] = true;
oscs[i].amp(0, 0.1);
stillPoints--;
stillPoints = constrain(stillPoints, 0, pointCount);
} else {
pointsMoving[i] = false;
oscs[i].amp(0.5, 0.1);
stillPoints++;
stillPoints = constrain(stillPoints, 0, pointCount);
}
}
}
for (var i = 0; i < pointCount; i++) {
var pointOffset = i * 2;
// var speed = Math.abs(prevxy[pointOffset] - curxy[pointOffset]);
var r = 8;
ellipse(curxy[pointOffset], curxy[pointOffset + 1], r, r);
}
}
}