MLNI Week 5: Bodypix Interactive Portraiture – Alex Wang

Task:

Create a generative and interactive portraiture that utilizes U-NET or BodyPix. The sketch needs to demonstrate proper use of pixel iteration and manipulation as well.

Final Product:

Process:

I first started by checking the individual parts that body pix was able to detect by coloring different parts using different colors

After that I decided to try and implement a clear contrast between the body and the background by changing the size of the ellipse drawn.

The next step I took was adding a light effect by calculating the distance between a certain coordinate to the position of the ellipse. Changing the rgb value of the ellipse fill.

I made this effect look even more like a light by decreasing the size of the ellipse as well as setting both red and blue to zero as it approaches max distance.

The final step I took was importing the gravitational orb code that I created for the OOP assignment and using that as the source of light.

Final Code:

console.log('ml5 version:', ml5.version);

var lastLoc = [];
var array = [];
var maxN = 100000;
var counter = 0;

let bodypix;
let cam;
let segmentation;
let test;
const options = {
outputStride: 8, // 8, 16, or 32, default is 16
segmentationThreshold: 0.3, // 0 - 1, defaults to 0.5
}

function setup() {
createCanvas(640, 480);
array[0] = new Spark(1,200,0,1,0);
cam = createCapture(cam);
cam.size(320, 240);
cam.hide();
bodypix = ml5.bodyPix(cam, modelReady);

//test = createVideo('hi.MOV');
//test.hide();
}

function draw() {
background(0);
//test.loadPixels();
for (var i = 0;i < array.length;i +=1){
if (array[i].alive()){
array[i].gravity();
array[i].motion();
array[i].show();
}

if (segmentation !== undefined) {
let w = segmentation.raw.width;
let h = segmentation.raw.height;
let data = segmentation.raw.data;

let gridSize = 5;
fill(255,0,255);
for (let y = 0; y < h; y+=gridSize) {
for (let x = 0; x < w; x+=gridSize) {
let index = x + y*w; // ***
let mappedX = map(x, 0, w, 0, width);
let mappedY = map(y, 0, h, 0, height);

let index2 = (x+y*width)*4;

if (data[index] == -1){

//textSize(10);
//text('.',mappedX, mappedY)
}
else if (data[index] >= 0){
noStroke();
let rvalue = (abs(dist(mappedX,mappedY,array[0].getposx(),array[0].getposy())))*1.2;
let bvalue = 255;
if (rvalue < 0){
rvalue=0;
bvalue = 0;
}
else if(rvalue>255){
rvalue=255;
}

let size = map(rvalue,0,200,10,1);
if (size < 0){
size=0;
}
//console.log(size);

fill(255-rvalue,0,bvalue);
ellipse(mappedX,mappedY,size,size);
//fill(255);
//ellipse(mappedX,mappedY,30,30);
//textSize(20);
}
else{

//fill(0);
}
//console.log(test.pixels);

//text('.',mappedX, mappedY);
//text(data[index], mappedX, mappedY);

}
}
}
}
}

///// bodypix functions /////

function modelReady() {
console.log('Model Ready!');
bodypix.segmentWithParts(gotResults, options);
}

function gotResults(error, result) {
if (error) {
console.log(error);
return;
}
segmentation = result;

//image(segmentation.image, 0, 0, width, height);
//console.log( segmentation.raw.data.length ); 320 * 240 - 1

bodypix.segmentWithParts(gotResults, options);
}

class Spark {
constructor(iteration,posx,posy,vx,vy){
this.iteration = iteration;
this.posx = posx;
this.posy = posy;
this.vx = vx;
this.vy = vy;
this.color = [255,100,255];

}
burst(){
//console.log("hi");
lastLoc = [this.posx,this.posy,this.vx,this.vy];
this.iteration+=1;
this.color = [(random(239)),random(255),10+random(8)*this.iteration]
this.vx = random(-4,4);
//append(array,new Spark(this.iteration +1,this.posx,this.posy,1,1));
}
gravity(){
this.vx *= 0.99;
this.vy *= 0.99;

if(this.posy < mouseY){
this.vy += 2;
}
else if (this.posy > mouseY){
this.vy -=2;
}
if(this.posx < mouseX){
this.vx += 2;
}
else if (this.posx > mouseX){
this.vx -=2;
}
}

motion(){
this.posx +=this.vx;
this.posy +=this.vy;
if(this.posx <= 0){
this.vx*=-1;
this.posx=1;

}
if(this.posx >= width){
this.vx*=-1;
this.posx=width-1;

}
if(this.posy <= 0){
this.vy*=-1;
this.posy=1;
//burst(this);
}
if(this.posy >= height){
this.vy*=-1;
this.posy=height-1;
if (this.iteration < 23){
//burst(this);
}
}

}
show(){
if (this.iteration < 23){
fill(this.color[0],this.color[1],this.color[2]);
ellipse(this.posx,this.posy,10);
}
}
alive(){
return this.iteration <= 22;
}
getposx(){
return this.posx;
}
getposy(){
return this.posy;
}
}

Leave a Reply