---
tags: 程式設計,期末作業,花朵,自畫像,視訊擷取
---
# 2021-01-05 程式設計期末報告

[](ttps://openprocessing.org/sketch/1419744#)
---
## 程式介紹
### 大綱
### * 第一步:啟用 HTML 模式
### * 第二步:先定義未來可能會用到的東西(var,let)
### * 第三步:擷取攝影機影像
### * 第四步:導入身體支架的程式碼
### * 第五步:加入耳、鼻(自動大小),並上傳圖片
### * 第六步:加入眼睛,左邊為隨機顏色花朵、右邊為上次期中作業
### * 完成!
---
## 第一步
### 啟用 HTML 模式

---
## 第二步
### 先定義未來可能會用到的東西(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)
```
---
## 第三步
### 擷取攝影機影像

```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);
}
}
```
---
## 第五步
### 加入耳、鼻(自動大小),並上傳圖片

```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()
}
```
---
## 第六步
### 加入眼睛,左邊為隨機顏色花朵、右邊為上次期中作業


```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
}
```