
My inspiration comes from the fogged-up car windows on rainy days; I always want to draw something on them with my hand.

My approach involves creating a mask layer and splitting the original camera-captured image into two parts. One part is blurred using a blur filter, and the other is covered with the mask. A circle is then drawn on the mask layer using index finger tracking in ml5. Finally, the blurred frame is shown first, and then the masked image is overlaid.

let cam, maskG;
let handPose;
let hands = [];
let dropX = [];
let dropY = [0,0,0];
let dspeed =[];
function preload() {
handPose = ml5.handPose();
}
function setup() {
pixelDensity(1);
createCanvas(640, 480);
cam = createCapture(VIDEO);
cam.size(640, 480);
cam.hide();
maskG = createGraphics(width, height);
// maskG.background(0);
handPose.detectStart(cam, gotHands);
for(let i= 0; i<3;i++){
dropX[i]=random(0,width);
dspeed[i]= random(0,2);
}
}
function draw() {
background(0);
let blurred = cam.get();
blurred.filter(BLUR, 5);
image(blurred, 0, 0, width, height);
fill(255, 255, 255, 60);
rect(0, 0, width, height);
maskG.noStroke();
maskG.fill(0);
for(let i =0; i<3;i++){
maskG.circle(dropX[i],dropY[i],10);
dropY[i] += dspeed[i];
}
if (hands.length > 0) {
let hand = hands[0];
let keypoint = hand.keypoints[8];
maskG.circle(keypoint.x, keypoint.y, 50);
}
cam.mask(maskG);
image(cam, 0, 0, width, height);
}
function gotHands(results) {
hands = results;
}
function keyPressed() {
if (key === 's' || key === 'S') {
saveCanvas('myDrawing', 'png');
}
}
The code is quite simple. However, it actually took me a lot of time because I initially thought that mask() worked based on the image's brightness. After a long period of experimentation, I finally discovered it actually works on the alpha value. But there's still a significant problem. I feel that the blur() function is very performance-intensive; it makes the image very laggy. Ideally, there would be a way to blur an image at the pixel level.