--- tags: 程式設計,期末作業,花朵,自畫像,視訊擷取 --- # 2021-01-05 程式設計期末報告 ![](https://i.imgur.com/4PwQg1r.jpg) [![](https://i.imgur.com/s26Uc9v.jpg)](ttps://openprocessing.org/sketch/1419744#) --- ## 程式介紹 ### 大綱 ### * 第一步:啟用 HTML 模式 ### * 第二步:先定義未來可能會用到的東西(var,let) ### * 第三步:擷取攝影機影像 ### * 第四步:導入身體支架的程式碼 ### * 第五步:加入耳、鼻(自動大小),並上傳圖片 ### * 第六步:加入眼睛,左邊為隨機顏色花朵、右邊為上次期中作業 ### * 完成! --- ## 第一步 ### 啟用 HTML 模式 ![](https://i.imgur.com/FSTy8xx.png) --- ## 第二步 ### 先定義未來可能會用到的東西(var,let) ```javascript= //我是 let 控制項 let video; let poseNet; let pose; let skeleton; //我是 var 控制項 var rightEarImg var myFlower var flowers=[] var colors = "d0e3cc-f7ffdd-fcfdaf-efd780-dba159".split("-").map(a=>"#"+a) var colors2 = "ffadad-ffd6a5-fdffb6-caffbf-9bf6ff-a0c4ff-bdb2ff-ffc6ff-fffffc".split("-").map(a=>"#"+a) ``` --- ## 第三步 ### 擷取攝影機影像 ![](https://i.imgur.com/5zLQ9Vi.png) ```javascript= function setup() { createCanvas(640, 480); //createCanvas(windowWidth, windowHeight); video = createCapture(VIDEO); // video.hide(); // poseNet = ml5.poseNet(video, modelLoaded); //呼叫在ml5.js上的net函數 poseNet.on('pose', gotPoses); } ``` --- ## 第四步 ### 導入身體支架的程式碼 ```javascript= function gotPoses(poses) { //console.log(poses); if (poses.length > 0) { pose = poses[0].pose; //把抓到的幾個點,都放置pose變數內 skeleton = poses[0].skeleton; //把相關於骨架的點都放到skeleton變數內 } } function modelLoaded() { //顯示"pose model"已經準備就緒 console.log('poseNet 已經就緒!'); } function drawKeypoints() { //描繪出重要的點 for (let i = 0; i < pose.keypoints.length; i++) { let x = pose.keypoints[i].position.x;//找出每一個點的x座標 let y = pose.keypoints[i].position.y;//找出每一個點的y座標 fill(0,255,0); ellipse(x,y,16,16); } } function drawSkeleton() { //描繪出骨架 for (let i = 0; i < skeleton.length; i++) { let a = skeleton[i][0]; let b = skeleton[i][1]; strokeWeight(4); stroke(255,0,0); line(a.position.x, a.position.y,b.position.x,b.position.y); } } ``` --- ## 第五步 ### 加入耳、鼻(自動大小),並上傳圖片 ![](https://i.imgur.com/m4F9NVV.png) ```javascript= //載入圖片 function preload(){ rightEarImg= loadImage("rightEar.png") noseImg= loadImage("nose.png") } //鼻 子 if(pose.nose.confidence>0.7){ push() translate(pose.nose.x, pose.nose.y+180*d/1000) imageMode(CENTER); scale(d/1000) image(noseImg,0, 0) pop() } //右 耳 if(pose.rightEar.confidence>0.7){ //放大縮小控制 push() translate(pose.rightEar.x, pose.rightEar.y) imageMode(CENTER); scale(-1,1) scale(d/1000) image(rightEarImg,0, 0) pop() } //左 耳 if(pose.leftEar.confidence>0.7){ //放大縮小控制 push() translate(pose.leftEar.x, pose.leftEar.y) imageMode(CENTER); scale(d/1000) image(rightEarImg,0, 0) pop() } ``` --- ## 第六步 ### 加入眼睛,左邊為隨機顏色花朵、右邊為上次期中作業 ![](https://i.imgur.com/85NzPd5.gif) ![](https://i.imgur.com/1feeSFq.png) ```javascript= if (pose) {   let eyeR = pose.rightEye; //抓到右眼資訊,放到eyeR   let eyeL = pose.leftEye; //抓到左眼資訊,放到eyeL   let d = dist(eyeR.x, eyeR.y, eyeL.x, eyeL.y); //右 眼 push()  let flower=generateRandomFlower(eyeR.x, eyeR.y)  flower.size=0.1  flowers.push(flower) pop() fill(255, 0, 0); //左 眼 push()  translate(pose.leftEye.x, pose.leftEye.y)  imageMode(CENTER); //圖片要以中心點為座標點  scale(d/1000)  draw_1(0,0) pop() } ``` ### 花朵程式碼(調用flower) ```javascript= // 這裡是花花 function drawFlower(flower){ push() translate(flower.x,flower.y); rotate(flower.size) if(flower.clr1) { fill(flower.clr1) } else { fill(255,211,33) } ellipse(0, 0, 50); ellipseMode(CORNER) if(flower.clr2) { fill(flower.clr2) } else { fill(255,90,61) } for(var i=0;i<16;i++){ ellipse(30, -20, 100*flower.size, 30); line(40,-5,120*flower.size,-5) rotate(PI/8) //180度產生八片,360度產生16片 } pop() } ``` ### 自畫像程式碼(調用draw1) ```javascript= //自訂 一 draw1 function draw_1(x,y){ var r1=mouseX //定義 var r2=mouseY //定義 var Color_R= r1/2+30 //定義 var Color_G= r1/2+50+r2 //定義 var Color_B= r1/2+10 //定義 fill(Color_R, Color_G, Color_B) noStroke(); ellipse(mouseX - 120, mouseY - 170, 150, 150); fill(128,42,42) noStroke(); ellipse(mouseX - 120, mouseY - 170, 100, 100); fill(255) noStroke(); ellipse(mouseX + 120, mouseY - 170, 150, 150); fill(128,42,42) noStroke(); ellipse(mouseX + 120, mouseY - 170, 100, 100); // ------ 臉部 ------ // fill(255, 225, 0); ellipse(mouseX, mouseY, 400, 400); // ------ 眼睛左邊 ------ // fill(0) noStroke(); ellipse(mouseX - 80, mouseY - 60, 100, 100); // ------ 眼睛右邊 ------ // fill(0) noStroke(); ellipse(mouseX + 80, mouseY - 60, 100, 100); // ------ 超大眼白 ------ // noFill(); stroke(255) strokeWeight(50); ellipse(mouseX - 80, mouseY - 60, 130, 130); ellipse(mouseX + 80, mouseY - 60, 130, 130); // ------ 微笑 ------ // stroke(0); strokeWeight(8); noFill(); arc(mouseX, mouseY, 300, 300, 0.25, PI - 0.25) //曲度width/2+ height/2 } ``` --- ### 完整程式碼 ```javascript= //我是 let 控制項 let video; let poseNet; let pose; let skeleton; //我是 var 控制項 var rightEarImg var myFlower var flowers=[] var colors = "d0e3cc-f7ffdd-fcfdaf-efd780-dba159".split("-").map(a=>"#"+a) var colors2 = "ffadad-ffd6a5-fdffb6-caffbf-9bf6ff-a0c4ff-bdb2ff-ffc6ff-fffffc".split("-").map(a=>"#"+a) //載入圖片 function preload(){ rightEarImg= loadImage("rightEar.png") noseImg= loadImage("nose.png") } function setup() { createCanvas(640, 480); //createCanvas(windowWidth, windowHeight); video = createCapture(VIDEO); // video.hide(); // poseNet = ml5.poseNet(video, modelLoaded); //呼叫在ml5.js上的net函數 poseNet.on('pose', gotPoses); } function gotPoses(poses) { //console.log(poses); if (poses.length > 0) { pose = poses[0].pose; //把抓到的幾個點,都放置pose變數內 skeleton = poses[0].skeleton; //把相關於骨架的點都放到skeleton變數內 } } function modelLoaded() { //顯示"pose model"已經準備就緒 console.log('poseNet 已經就緒!'); } function draw() { background(0); translate(video.width,0) scale(-1,1) //反轉畫面 image(video, 0, 0); //顯示攝影機畫面 if (pose) { let eyeR = pose.rightEye; //抓到右眼資訊,放到eyeR let eyeL = pose.leftEye; //抓到左眼資訊,放到eyeL let d = dist(eyeR.x, eyeR.y, eyeL.x, eyeL.y); //右 眼 push() let flower=generateRandomFlower(eyeR.x, eyeR.y) flower.size=0.1 flowers.push(flower) pop() fill(255, 0, 0); //左 眼 push() translate(pose.leftEye.x, pose.leftEye.y) imageMode(CENTER); //圖片要以中心點為座標點 scale(d/1000) draw_1(0,0) pop() //鼻 子 if(pose.nose.confidence>0.7){ push() translate(pose.nose.x, pose.nose.y+180*d/1000) imageMode(CENTER); //scale(-1,1) scale(d/1000) image(noseImg,0, 0) pop() } //右 耳 if(pose.rightEar.confidence>0.7){ //放大縮小控制 push() translate(pose.rightEar.x, pose.rightEar.y) imageMode(CENTER); scale(-1,1) scale(d/1000) image(rightEarImg,0, 0) pop() } //左 耳 if(pose.leftEar.confidence>0.7){ //放大縮小控制 push() translate(pose.leftEar.x, pose.leftEar.y) imageMode(CENTER); //scale(-1,1) scale(d/1000) image(rightEarImg,0, 0) pop() } fill(0, 0, 255); ellipse(pose.rightWrist.x, pose.rightWrist.y, 62); //畫出右手腕圓圈 ellipse(pose.leftWrist.x, pose.leftWrist.y, 62); //畫出左手腕圓圈 for(var i=0;i<flowers.length;i++){ let flower = flowers[i] drawFlower(flower) } flowers.splice(flower) } } function drawKeypoints() { //描繪出重要的點 for (let i = 0; i < pose.keypoints.length; i++) { let x = pose.keypoints[i].position.x;//找出每一個點的x座標 let y = pose.keypoints[i].position.y;//找出每一個點的y座標 fill(0,255,0); ellipse(x,y,16,16); } } function drawSkeleton() { //描繪出骨架 for (let i = 0; i < skeleton.length; i++) { let a = skeleton[i][0]; let b = skeleton[i][1]; strokeWeight(4); stroke(255,0,0); line(a.position.x, a.position.y,b.position.x,b.position.y); } } function generateRandomFlower(x,y){ //隨機產生花 return{ x: x || random(width), y:y || random(height), size: random(4), clr1:random(colors), clr2:random(colors2) } } // 這裡是花花 function drawFlower(flower){ push() translate(flower.x,flower.y); rotate(flower.size) if(flower.clr1) { fill(flower.clr1) } else { fill(255,211,33) } ellipse(0, 0, 50); ellipseMode(CORNER) if(flower.clr2) { fill(flower.clr2) } else { fill(255,90,61) } for(var i=0;i<16;i++){ ellipse(30, -20, 100*flower.size, 30); line(40,-5,120*flower.size,-5) rotate(PI/8) //180度產生八片,360度產生16片 } pop() } //自訂 一 draw1 function draw_1(x,y){ var r1=mouseX //定義 var r2=mouseY //定義 var Color_R= r1/2+30 //定義 var Color_G= r1/2+50+r2 //定義 var Color_B= r1/2+10 //定義 fill(Color_R, Color_G, Color_B) noStroke(); ellipse(mouseX - 120, mouseY - 170, 150, 150); fill(128,42,42) noStroke(); ellipse(mouseX - 120, mouseY - 170, 100, 100); fill(255) noStroke(); ellipse(mouseX + 120, mouseY - 170, 150, 150); fill(128,42,42) noStroke(); ellipse(mouseX + 120, mouseY - 170, 100, 100); // ------ 臉部 ------ // fill(255, 225, 0); ellipse(mouseX, mouseY, 400, 400); // ------ 眼睛左邊 ------ // fill(0) noStroke(); ellipse(mouseX - 80, mouseY - 60, 100, 100); // ------ 眼睛右邊 ------ // fill(0) noStroke(); ellipse(mouseX + 80, mouseY - 60, 100, 100); // ------ 超大眼白 ------ // noFill(); stroke(255) strokeWeight(50); ellipse(mouseX - 80, mouseY - 60, 130, 130); ellipse(mouseX + 80, mouseY - 60, 130, 130); // ------ 微笑 ------ // stroke(0); strokeWeight(8); noFill(); arc(mouseX, mouseY, 300, 300, 0.25, PI - 0.25) //曲度width/2+ height/2 } ```