---
# System prepended metadata

title: 2021-01-05 程式設計期末報告

---


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