人臉、顏色追蹤
人臉追蹤並不是人臉辨識,而是純粹判斷五官而追蹤人臉 ( 畢竟如果只是「純前端」而沒有後端資料庫,要做到人臉辨識應該有難度 ),透過人臉與顏色的追蹤,將追蹤的數值套用到智慧插座裡,就可以做出許多意想不到的有趣效果。
相關 Webduino 教學參考:LED ( 人臉追蹤 )
微軟人臉辨識 API:Face API
人臉、顏色追蹤初體驗
如果是透過 Webduino Blockly 線上編輯工具 ( https://blockly.webduino.io ),可以使用現成的人臉追蹤或顏色追蹤積木,來執行相對應的動作。( 要執行的話切記一定要是「https」,因啟動相機無法在 http 的模式下進行 )
Webduino Blockly 人臉追蹤:https://goo.gl/B3Cce0
Webduino Blockly 顏色追蹤:https://goo.gl/zJfTRv
顏色追蹤
使用的方法和 Webduino 一模一樣,是採用一個名為「tracking.js」的 JavaScript,它提供了人臉、顏色...等追蹤的方法。
要使用 tracking.js,首先必須載入相對應的 JavaScript,tracking.js 預設可以追蹤顏色。
<script src="https://blockly.webduino.io/lib/tracking-min.js"></script>
追蹤的方式是先透過電腦的攝影機擷取影像,透過網頁 video
的標籤顯示出來,因此 HTML 一開始要先放入 video
,然後這裡可以在外層多加一個 div
作為定位。
<div id="demo">
<video id="demo-vedio" preload="" autoplay="" loop="" muted="" controls=""></video>
</div>
然後因為這邊要把追蹤到的顏色或是人臉,用一個對應的顏色方框顯示出來 ( 有這個顏色的區域外層用一個矩形框住,矩形邊框的顏色就是偵測到的顏色,如果是人臉也會指定一個外框顏色 ),雖然標記用的矩形是動態產生,我們仍然可以先從 CSS 設定好它的一些基本屬性,到這邊一些基本的步驟就完成了。
#demo {
position: relative;
width: 400px;
height: 300px;
}
#demo-video {
position: absolute;
z-index:1;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
#demo div{
position:absolute;
z-index:2;
}
首先看到顏色追蹤 ( 預設功能 ),官方範例提供三種預設可追蹤的顏色。
track.myTracker = new tracking.ColorTracker(["magenta", "cyan", "yellow"]);
不過因為只有追蹤三種顏色還是太少,可以自己添加追蹤的顏色數量,透過 .registerColor
的方法,自行添加顏色,不過這邊要注意的是,添加的顏色是用 RGB 的範圍來定義,因為雖然眼睛以為是紅色,透過攝影機的電腦卻不見得認為是紅色 ( 舉例來說,藍色的東西在紅色的光下面,看起來就偏紫色,白紙在黃光下就會變成黃色是一樣的道理 ),所以才需要定義範圍。( 不過同樣的,環境光線常會影響顏色判斷,最好是用白光測試比較準確 )
tracking.ColorTracker.registerColor("red", function(r, g, b) {
if (r > 160 && g < 80 && b < 80) {
return true;
}
return false;
});
tracking.ColorTracker.registerColor("green", function(r, g, b) {
if (r < 80 && g > 160 && b < 80) {
return true;
}
return false;
});
tracking.ColorTracker.registerColor("blue", function(r, g, b) {
if (r < 80 && g < 80 && b > 160) {
return true;
}
return false;
});
定義好顏色後,我這邊另外用了一個物件,把對應邊框的顏色寫在裡面。
track.storkColor = {
magenta: "#f0a",
red: "#f00",
cyan: "#0ff",
yellow: "#ff0",
green: "#0c0",
blue: "#00f"
};
接著就是要啟動攝影機。
track.trackerTask = tracking.track("#demo-video", track.myTracker, {
camera: true
});
透過 .on('track')
的方法,就可以開始追蹤顏色,而這邊 event.data.length
表示追蹤到的顏色總數,如果你拿兩個黃色物體,長度就會是 2,你拿一個紅一個黃,長度也會是 2,也因此當數量不為 0,就表示有追蹤到顏色。
track.myTracker.on('track', function(event) {
if (event.data.length === 0) {
// No colors were detected in this frame.
} else {
event.data.forEach(function(rect) {
// rect.x, rect.y, rect.height, rect.width, rect.color
});
}
});
到這邊差不多就完成顏色追蹤了,看一下完整的 JavaScript,最主要就是根據顏色的數量,產生對應數量的 div 作為方框來追蹤,當顏色數量改變或沒有追蹤到顏色時,再動態的調整 div 的數量,而 div 的顏色則是根據我們剛剛設定的邊框顏色物件來決定。
$(function(){
var track = {};
var $demo = $('#demo');
tracking.ColorTracker.registerColor("red", function(r, g, b) {
if (r > 160 && g < 80 && b < 80) {
return true;
}
return false;
});
tracking.ColorTracker.registerColor("green", function(r, g, b) {
if (r < 80 && g > 160 && b < 80) {
return true;
}
return false;
});
tracking.ColorTracker.registerColor("blue", function(r, g, b) {
if (r < 80 && g < 80 && b > 160) {
return true;
}
return false;
});
track.myTracker = new tracking.ColorTracker(["magenta", "cyan", "yellow", "red", "green", "blue"]);
track.storkColor = {
magenta: "#f0a",
red: "#f00",
cyan: "#0ff",
yellow: "#ff0",
green: "#0c0",
blue: "#00f"
};
track.trackerTask = tracking.track("#demo-video", track.myTracker, {
camera: true
});
track.myTracker.on("track", function(event) {
if (event.data.length === 0) {
$('#demo div').remove(); //如果沒偵測到顏色,移除所有自動產生的追蹤方框
} else {
$('#demo div').remove(); //一開始搜尋到顏色時,先清空對應的追蹤方框
var divLength = event.data.length; //獲取顏色數量
event.data.forEach(function(e,i){
if($('#demo .div'+i).length === 0){
$('#demo').append('<div class="div'+i+'"></div>'); //產生對應的追蹤方框
}
//設定追蹤方框樣式
$('#demo .div'+i).css({
'border-width':'3px',
'border-style':'solid',
'border-color':track.storkColor[e.color],
'left':e.x,
'top':e.y,
'width':e.width,
'height':e.height
});
});
}
});
});
完整程式碼:https://bin.webduino.io/corav/1/edit?html,css,js,output
要執行的話切記一定要是「https」,因啟動相機無法在 http 的模式下進行。
人臉追蹤
看完了顏色追蹤接著看人臉追蹤,原理其實都差不多,只是如果要追蹤人臉,必須額外載入「face-min.js」。
<script src="https://blockly.webduino.io/lib/face-min.js"></script>
和顏色追蹤的差別只在於第一段,顏色追蹤是設定追蹤的顏色名稱以及範圍,而人臉追蹤則是一些預設的參數。( 官方預設是這些參數 )
track.myTracker = new tracking.ObjectTracker("face");
tracker.setInitialScale(4);
tracker.setStepSize(2);
tracker.setEdgesDensity(0.1);
最後的程式碼長相,CSS 的部分和剛剛顏色追蹤一模一樣,JavaScript 就只是把追蹤到的人臉用紅色方框表示出來。
$(function(){
var track = {};
var $demo = $('#demo');
track.myTracker = new tracking.ObjectTracker("face");
track.myTracker.setInitialScale(4);
track.myTracker.setStepSize(0.5); //官方預設2,數值比較小比較不會抖動,但相對較吃效能
track.myTracker.setEdgesDensity(0.1);
track.trackerTask = tracking.track("#demo-video", track.myTracker, {
camera: true
});
track.myTracker.on("track", function(event) {
if (event.data.length === 0) {
$('#demo div').remove(); //如果沒偵測到人臉,移除所有自動產生的追蹤方框
} else {
$('#demo div').remove(); //一開始搜尋到人臉時,先清空對應的追蹤方框
var divLength = event.data.length; //獲取人臉數量
event.data.forEach(function(e,i){
if($('#demo .div'+i).length === 0){
$('#demo').append('<div class="div'+i+'"></div>'); //產生對應的追蹤方框
}
//設定追蹤方框樣式
$('#demo .div'+i).css({
'border-width':'3px',
'border-style':'solid',
'border-color':'#f00',
'left':e.x,
'top':e.y,
'width':e.width,
'height':e.height
});
});
}
});
});
程式:https://bin.webduino.io/mofor/1/edit?html,css,js,output
要執行的話切記一定要是「https」,因啟動相機無法在 http 的模式下進行。
透過顏色追蹤點亮燈泡
到這邊大致上已經掌握顏色追蹤以及人臉追蹤的原理,再來就是和智慧插座結合。首先用顏色追蹤,讓追蹤到黃色的時候會開燈,追蹤到藍色的時候會熄燈。
$(function(){
var track = {};
var $demo = $('#demo');
var led;
tracking.ColorTracker.registerColor("red", function(r, g, b) {
if (r > 160 && g < 80 && b < 80) {
return true;
}
return false;
});
tracking.ColorTracker.registerColor("green", function(r, g, b) {
if (r < 80 && g > 160 && b < 80) {
return true;
}
return false;
});
tracking.ColorTracker.registerColor("blue", function(r, g, b) {
if (r < 80 && g < 80 && b > 160) {
return true;
}
return false;
});
track.myTracker = new tracking.ColorTracker(["magenta", "cyan", "yellow", "red", "green", "blue"]);
track.storkColor = {
magenta: "#f0a",
red: "#f00",
cyan: "#0ff",
yellow: "#ff0",
green: "#0c0",
blue: "#00f"
};
track.trackerTask = tracking.track("#demo-video", track.myTracker, {
camera: true
});
boardReady({device: '你的裝置 ID'}, function (board) {
board.systemReset();
board.samplingInterval = 250;
led = getLed(board, 10);
track.myTracker.on("track", function(event) {
if (event.data.length === 0) {
$('#demo div').remove(); //如果沒偵測到顏色,移除所有自動產生的追蹤方框
} else {
$('#demo div').remove(); //一開始搜尋到顏色時,先清空對應的追蹤方框
var divLength = event.data.length; //獲取顏色數量
event.data.forEach(function(e,i){
if($('#demo .div'+i).length === 0){
$('#demo').append('<div class="div'+i+'"></div>'); //產生對應的追蹤方框
}
//設定追蹤方框樣式
$('#demo .div'+i).css({
'border-width':'3px',
'border-style':'solid',
'border-color':track.storkColor[e.color],
'left':e.x,
'top':e.y,
'width':e.width,
'height':e.height
});
if(e.color=='yellow'){
console.log('yellow'); //追蹤到黃色的時候亮燈
led.on();
}else{
led.off(); //不然就是都熄燈
}
});
}
});
});
});
完整程式碼:https://bin.webduino.io/neba/1/edit?html,css,js,output
透過人臉追蹤點亮燈泡
至於人臉追蹤,這邊用人臉的 x 數值來追蹤,預設追蹤到的 x,y 數值是對應到 video 的左上角,這也是為什麼我們可以拿來作為 CSS 位置的主要原因。因為我用的 video 寬度為 360,所以我讓 x 數值大於 ( 180 - 追蹤框寬度/2 ) 的時候就亮燈,也就是臉往右邊移動超過中線的時候會開燈。
$(function(){
var track = {};
var $demo = $('#demo');
var led;
track.myTracker = new tracking.ObjectTracker("face");
track.myTracker.setInitialScale(4);
track.myTracker.setStepSize(0.5);
track.myTracker.setEdgesDensity(0.1);
track.trackerTask = tracking.track("#demo-video", track.myTracker, {
camera: true
});
boardReady({device: 'evkG'}, function (board) {
board.systemReset();
board.samplingInterval = 250;
led = getLed(board, 10);
track.myTracker.on("track", function(event) {
if (event.data.length === 0) {
$('#demo div').remove(); //如果沒偵測到人臉,移除所有自動產生的追蹤方框
} else {
$('#demo div').remove(); //一開始搜尋到人臉時,先清空對應的追蹤方框
var divLength = event.data.length; //獲取人臉數量
event.data.forEach(function(e,i){
if($('#demo .div'+i).length === 0){
$('#demo').append('<div class="div'+i+'"></div>'); //產生對應的追蹤方框
}
//設定追蹤方框樣式
$('#demo .div'+i).css({
'border-width':'3px',
'border-style':'solid',
'border-color':'#f00',
'left':e.x,
'top':e.y,
'width':e.width,
'height':e.height
});
//設定超過中線會亮燈
if(e.x>(180-e.width/2)){
led.on();
}else{
led.off();
}
});
}
});
});
});
完整程式碼:https://bin.webduino.io/pufaqe/1/edit?html,css,js,output
小結
整體而言了解智慧插座的控制後,就可以用各種方法來操控,當然人臉追蹤與顏色追蹤,都只是廣大控制方式的一部分,後續會介紹更多有趣的控制方法喔!
參考:
- tracking.js:https://trackingjs.com
- 綜合應用:LED ( 人臉追蹤 )
聯絡我們
如果對於 Webduino 產品有興趣,歡迎透過下列方式購買:
個人線上購買:https://store.webduino.io/ ( 支援信用卡、超商取貨付款 )
企業&學校採購:來信 [email protected] 或來電 07-3388511。
如果對於這篇教學有任何問題或建議,歡迎透過下列方式聯繫我們:
Email:[email protected] ( 如對於產品有使用上的問題,建議透過 Email 附上照片或影片聯繫 )
Facebook 粉絲團:https://www.facebook.com/webduino/
Facebook 技術討論社團:https://www.facebook.com/groups/webduino/