我嘗試使用google的機器學習服務Vision API使用網路攝影機進行人臉檢測

最近,“機器學習”這個詞已經擠滿了AlphaGo等非凡的活動,但您知道“ Google Cloud Vision API ”(以下稱為“Vision API”)嗎?
Vision API是一種使用谷歌機器學習模型的圖像識別服務。
官方網址:https://cloud.google.com/vision/h

如果您說“機器學習”,您可能認為您需要專業知識,例如深度學習,但在使用Vision API時不需要這些知識。
Vision API僅使用Google學習的機器學習模型,因此用戶可以將基於64位編碼的圖像數據(* 1)和圖像檢測類型(OCR或面部檢測)添加到Vision API URL。您可以通過POST等分析圖像中的內容和情況。
例如,當通過面部檢測功能處理具有人臉的圖像時,從圖像中的面部和眼睛和鼻子的位置信息以及面部表情返回情緒的預測結果。

※1)和base64編碼的圖像數據,使用64種類型的字母數字的,用於處理多字節字符或二進制數據中不能被處理的其他字符的通信環境中的編碼方法。

這一次,最多的描述將能夠使用這樣的Vision API,可以實現任何人,我想向大家介紹一個Web應用程序的人臉檢測近實時使用Vision API和PC網路攝影機。

目錄

  • 創建GCP項目
  • 啟動Vision API服務
    • 單擊項目儀表板屏幕左上角的菜單圖標
    • 從菜單中選擇“API Manager”
    • 在API列表屏幕的搜索窗口中輸入“vision”並蒐索API
    • 從API搜索結果中選擇“Google Cloud Vision API”
    • 激活Vision API服務
    • 從屏幕上檢查是否啟用了Vision API服務
  • 創建Vision API的API密鑰
    • 轉換到“API Manager”的“憑據”屏幕
    • 單擊要創建的憑據的API密鑰
    • 選擇API密鑰的類型
    • 創建API密鑰
    • 確認
  • 運行Web應用程序
  • Web應用程序代碼說明
    • 步驟1.啟動網路攝像頭
    • 步驟2.獲取捕獲的網路攝像頭視頻圖像
    • 步驟3. Base64將捕獲的圖像和POST編碼到Vision API URL
    • 步驟4.取出面部的坐標位置並將其繪製在屏幕上
  • 摘要

創建GCP項目

Vision API是GCP服務,因此需要GCP項目。
首先,讓我們創建一個GCP項目來運行Vision API。閱讀“ 初學者GCP項目入門
”,了解有關創建項目的說明。

要使用Vision API服務,您需要設置費用,因此請自行設置項目風險。
此外,請查看官方頁面,了解Vision API使用費的詳細信息。
*雖然Vision API需要收費設置,但截至2016年7月22日,使用API​​有一定的免費框架,因此即使在免費框架內使用收費設置使用不收費。

啟動Vision API服務

創建GCP項目後,下一步是啟動Vision API服務。
※根據使用的環境,語言設定可能不同,但是按鈕的安排是相同的。請適當地工作,改變您使用的環境。

單擊項目儀表板屏幕左上角的菜單圖標

從菜單中選擇“API Manager”

在API列表的搜索窗口中輸入“vision”並蒐索API

從API搜索結果中選擇“Google Cloud Vision API”

啟動Vision API服務

從螢幕上檢查是否啟用了Vision API服務

我認為Vision API的服務是通過上述過程啟用的。

創建Vision API的API密鑰

現在啟用了Vision API服務,讓我們創建使用API​​所需的API密鑰。

轉換到“API Manager”的“憑據”螢幕

單擊要創建的憑據的API密鑰

選擇API密鑰的類型

由於幾乎實時檢測面部的Web應用程序在瀏覽器中使用Javascript的Vision API,因此請選擇“瀏覽器密鑰”。

3.3瀏覽器 - 按鍵 - 單擊

創建API密鑰

3.4創建

“名稱”和“接受來自這些HTTP引用者(網站)的請求”仍為默認值。
這兩個項目可以在以後更改,所以現在可以保留默認值。

確認

當“Creadentials”列表中顯示名稱“Browser key 1”時,如下圖所示,您已經創建了一個API密鑰。

Key字段中的值是API密鑰字符串。
從現在開始,我們將使用此密鑰字符串向Vision API發出請求,因此請複製它。

運行Web應用程序

到目前為止,我們已經創建了一個API密鑰。
首先,讓我們嘗試使用這個API密鑰在演示環境中引入什麼樣的應用程序。
請訪問以下URL的頁面。

網址:https://near-realtime-face-detection-dot-apps-gcp-sample.appspot.com/near-realtime-face-detection.html

如何使用,當顯示以下屏幕時,只需在“API密鑰”輸入字段中輸入“3.為API API創建API API”中創建的API密鑰字符串,然後按“開始”按鈕。
※使用創建API密鑰的項目的資源。如果超出可用空間,則需要為您為其創建API密鑰的項目付費。

4.1

如果在啟動網路攝影機後人物的臉部出現在相機上,則每個情緒和帽子的估計結果將如下圖所示顯示,並且人物的臉部將被方框包圍。
由於這個應用程序“幾乎”是實時的,它可以檢測到人臉,並且在它被平方之前有一點時滯。

4.2

Vision API的面部檢測功能返回有關圖像部分坐標的信息,例如面部,眼睛和鼻子,以及從表情中讀取的情緒。
※因為不歸屬於全名的個人信息的東西所以請注意。
如果您查看官方頁面,返回信息的詳細信息會更快,請參閱以下頁面。
網址: https://cloud.google.com/vision/reference/rest/v1/images/annotate#FaceAnnotation

另外,通過替換Vision API的返回值來顯示情緒估計結果的%指示,如下表所示。

Vision API的實際返回值Web應用程序上顯示的值
UNKNOWN不可測
VERY_UNLIKELY可能性1%
UNLIKELY可能性25%
POSSIBLE50%的可能性
LIKELY可能性75%
VERY_LIKELY99%的可能性

Web應用程序代碼說明

在評論之前,有一點需要注意,但這次我不會評論完整的代碼。
我將僅解釋主要處理。
如果您想知道完整代碼,可以在這裡查看
※由於此應用程序使用CDN(※2)讀取所有必需的CSS和Javascript,因此它適用於一個HTML文件,因此它僅通過複製工作。

* 2)內容分發網路。優化用於通過Internet提供內容的網路。

接下來,我想解釋一下Web應用程序的代碼。處理分為以下4個過程。

步驟1. 啟動網路攝影機
步驟2. 獲取web的運動圖像的捕獲圖像
步驟3. Base64編碼捕獲的圖像並POST到Vision API的URL
步驟4. 取出面部的坐標位置並在屏幕上顯示繪製

步驟1.啟動網路攝影機

該過程從$ scope.startFilming函數開始。
 代碼

它寫在第46行到“ near-realtime-face-detection.html ”的第95行。

var HAS_GET_USER_MEDIA = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; // 檢查它是否與網路攝影機兼容 

// 用網路攝影機開始拍攝
$scope.localMediaStream = null;
// startFilming函數是“START”按鈕的單擊事件$scope.startFilming = function() {
if (!HAS_GET_USER_MEDIA) {
alert("它是一個不支持網路攝影機的瀏覽器。");
return;
}

if (!$scope.apiKey) {
alert("請輸入API密鑰") return;
}

if ($scope.filming === true) {
// 網路攝影機處於活動狀態時不執行處理。
return;
}

var webCamera = document.getElementById('webCamera');
window.URL = window.URL || window.webkitURL;
navigator.getUserMedia = HAS_GET_USER_MEDIA;
navigator.getUserMedia({video: true}, function(stream) {
// 從網路攝影機的LocalMediaStream對象創建一個URL,
// 將URL指定為視頻來源。
webCamera.src = window.URL.createObjectURL(stream);
$scope.localMediaStream = stream;
$scope.filming = true; // 在網路攝影機啟動期間設置標誌
// 將STEP2處理設置為以1000毫秒的間隔執行
$scope.captureProcessId = setInterval($scope.capture,1000)
// 無法啟動網路攝像頭時,onFailSoHard功能是一個錯誤過程
}, onFailSoHard);
}

// Web攝影機啟動錯誤時的處理
var onFailSoHard = function(e) {
// 如果無法啟動網路攝影機,將發出錯誤警報。
alert("沒有網路攝像頭,或者它是不受支持的瀏覽器。 \n錯誤內容:" + e);
console.log('錯誤!', e);
};

// 網路攝影機停止
// stopFilming函數是“STOP”按鈕的單擊事件
$scope.stopFilming = function() {
$scope.filming = false;
if (!$scope.localMediaStream) {
return;
}
// 調用視頻元素的暫停功能以停止網路攝影機
document.getElementById('webCamera').pause() 
}

步驟2.獲取捕獲的網路攝影機視頻圖像

它寫在第98行 – 第134行“ near-realtime-face-detection.html ”。
 代碼

$scope.capture = function() { 
if ($scope.filming != true || !$scope.localMediaStream) {
clearInterval($scope.captureProcessId)
return;
}

var webCamera = document.getElementById('webCamera'); // 獲取網路攝影機的顯示元素
var vw = webCamera.videoWidth // 獲取網路影機視頻的寬度
var hw = webCamera.videoHeight // 獲取網路攝影機視頻的高度
$("#webCameraPic").attr("width", vw);// 將網路攝影機的寬度設置為畫面的寬度,該畫面在正方形中顯示圍繞面的框架
$("#webCameraPic").attr("height", hw);// 將網路攝影機的高度設置為畫面的高度,該高度顯示正方形中圍繞面的框架
$("#webCameraPicTemp").attr("width", vw);// 將網路攝像頭的寬度設置為不可見畫面的寬度,以生成網路攝影機捕獲圖像
$("#webCameraPicTemp").attr("height", hw);// 將網路攝影機的高度設置為不可見畫面的高度,以生成網路攝影機捕獲圖像

var position = $("#webCamera").position();
var scrollTop = $("#result").scrollTop();
$("#webCameraPic").css("top", position.top + scrollTop);

var webCameraPicTemp = document.getElementById('webCameraPicTemp');
var webCameraPicTempCtx = webCameraPicTemp.getContext('2d');
webCameraPicTempCtx.clearRect(0, 0, webCameraPicTemp.width, webCameraPicTemp.height);

if ($scope.localMediaStream) {
// 清除圖形,因為上次捕獲時仍有方形圖像
var webCameraPic = document.getElementById('webCameraPic');
var webCameraPicCtx = webCameraPic.getContext('2d');
webCameraPicCtx.clearRect(0, 0, webCameraPic.width, webCameraPic.height);

// 在隱藏的畫面上繪製攝影機捕獲的圖像
webCameraPicTempCtx.drawImage(webCamera, 0, 0, webCameraPicTemp.width, webCameraPicTemp.height);
var base64FileData = webCameraPicTemp.toDataURL('image/webp');
// 通過捕獲圖像傳遞到面部檢測過程
$scope.faceDetection('webCameraPic', base64FileData.split("base64,")[1]);
}
}

步驟3. Base64將捕獲的圖像和POST編碼到Vision API URL

它寫在第141行到第204行“ near-realtime-face-detection.html ”。

// 人臉檢測處理
$scope.faceDetection = function(canvasId, base64FileData) {
if (!base64FileData) {
// 如果沒有圖像數據,則會顯示警報並結束
alert("沒有捕獲數據。")
return;
}
$scope.canvasId = canvasId;

// 向Vision API創建請求數據
// 將Base64編碼的圖像數據設置為圖像上下文
// 將'FACE_DETECTION'設置為特徵類型的面部檢測功能的值
// 通過更改類型,您可以使用其他功能,如商標和OCR
// 讓我們將1個或更多的數值設置為特徵的maxResults
var data = {
"requests":[
{
"image":{
"content": base64FileData
},
"features":[
{
"type":"FACE_DETECTION",
"maxResults":100
}
]
}
],
}
// POST到Vision API端點
$http.post(VISION_API_URL + $scope.apiKey, data).success(function(data, status, headers, config) {
console.log(data)

var cvs = document.getElementById($scope.canvasId);
var ctx = cvs.getContext("2d");
var responses = data.responses;
angular.forEach(responses, function(response, key) {
$scope.faceAnnotations = response.faceAnnotations;
if (!$scope.faceAnnotations) {
angular.forEach($scope.faceAnnotations, function(faceAnnotation, key) {
// 獲取包括頭部的坐標信息
var boundingPolyVertices = faceAnnotation.boundingPoly.vertices;
// 在臉部周圍畫一個方框
var result = drawLine(boundingPolyVertices, ctx, $scope.colors[key]["VERY_LIKELY"]);
if (result == 1) {
// 如果你無法識別包括頭部在內的整個臉部,只能得到不包括頭部的臉部部分的坐標信息
var fdBoundingPolyVertices = faceAnnotation.fdBoundingPoly.vertices;
// 變成STEP4的處理
result = drawLine(fdBoundingPolyVertices, ctx,  $scope.colors[key]["VERY_LIKELY"]);
}
})
}
})

$scope.canvasId = null;
}).error(function(data, status, headers, config) {
console.log("error")
console.log(data) $scope.canvasId = null;
});
}

步驟4.取出面部的坐標位置並將其繪製在螢幕上

它寫在第206行到“ near-realtime-face-detection.html ”的第238行。

function drawLine(vertices, ctx, strokeStyle) { 
// 取出圍繞臉部的四點坐標
var x1 = vertices[0].x;
var y1 = vertices[0].y;
var x2 = vertices[1].x;
var y2 = vertices[1].y;
var x3 = vertices[2].x;
var y3 = vertices[2].y;
var x4 = vertices[3].x;
var y4 = vertices[3].y;

if (x1 && y1 && x2 && y2 && x3 && y3 && x4 && y4) {
// 當獲得4個點的位置信息時,在每個坐標之間畫一條線
ctx.beginPath();

ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.moveTo(x2, y2);
ctx.lineTo(x3, y3);
ctx.moveTo(x3, y3);
ctx.lineTo(x4, y4);
ctx.moveTo(x4, y4);
ctx.lineTo(x1, y1);

ctx.lineWidth = 3;
ctx.strokeStyle = strokeStyle;
ctx.stroke();
return 0;
}

// 如果無法獲取坐標,則不會繪製
return 1;
}

摘要

這是Web應用程序描述的結束,該應用程序幾乎可以實時執行面部檢測,任何人都可以創建。
您可以使用Vision API輕鬆創建一個。
除了面部檢測之外,Vision API還具有對象檢測和OCR等功能,因此可用於各種應用。
例如,當您要檢測對象時,請指定“LABEL_DETECTION”作為請求[0] .featurest [0] .type的值,該值由步驟3中的$ scope.faceDetection函數創建,如下所示。它只是將請求發送到與用於面部檢測的URL相同的URL。
※返回值因指定功能而異。請查看官方文檔,了解OCR功能等詳細信息。

var data = { 
"requests":[
{
"image":{
"content": base64FileData
},
"features":[
{
"type":"LABEL_DETECTION", "maxResults":100
}
]
}
]
}

此外,雖然截至2018年04月01日谷歌提供的機器學習API有限預覽,但還有一個名為Google Cloud Speech API的語音識別服務,未來將進一步增強google機器學習領域的服務我想它可能會到來。

Aaron Lee

超過6年的Google Cloud經驗,服務過上百家G Suite與GCP客戶,擔任多次研討會主講人與教育訓練講師,提供架構諮詢與技術支援,幫助各大企業上雲。

發佈留言