影片會議玩消失?藉助神器TensorFlow.js,200行程式碼教你「隱身」,GitHub標星3k+
- 2020 年 3 月 6 日
- 筆記
大數據文摘出品
作者:曹培信
疫情期間,許多公司都開啟了遠程辦公,試想一下,在影片會議時,如果你的同事突然從鏡頭中消失,大家會有什麼樣的反應?
Google網站工程師Jason Mayes就做了這麼一個項目,成功嚇到了自己的盆友。通過TensorFlow.js製作了一個插件,可以讓系統分離人物和背景,然後從場景中實時刪除任何人,也就是說,可以從影片中讓人「消失」。
從處理影片的效果來看,隱身的效果還不錯。

當然,除了文章開頭提到的「隱身「惡作劇,Jason也想到了不少有趣的應用場景。比如幫一個BBC在線連線的「翻車」影片做消除處理:從這兩個小孩「囂張」地走進來到被「無情」地拎走,都被Jason的小插件處理的一乾二淨。

推特上的粉絲也表示,這確實很有趣,也很神奇。

目前,該項目在GitHub上的標星已超過三千。

項目地址:
https://github.com/jasonmayes/Real-Time-Person-Removal
藉助神器TensorFlow.js,200行程式碼實現「隱身」
除了在GitHub放出項目,作者也在codepen.io網站上放出了所有的程式碼,其JS程式碼只有短短200多行。
文摘菌也仔細學習了一下,值得注意的是,這個項目本身沒有訓練新的模型,用的是TensorFlow.js現成的模型,然後通過演算法對影片進行了處理,體現的是巧妙的工程思維。
首先,作者利用TensorFlow.js提供的身體分割模型識別出的人體,並定義一個人體區域。
// Go through pixels and figure out bounding box of body pixels. for (let x = 0; x < canvas.width; x++) { for (let y = 0; y < canvas.height; y++) { let n = y * canvas.width + x; // Human pixel found. Update bounds. if (segmentation.data[n] !== 0) { if(x < minX) { minX = x; } if(y < minY) { minY = y; } if(x > maxX) { maxX = x; } if(y > maxY) { maxY = y; } foundBody = true; } } } // Calculate dimensions of bounding box. var width = maxX - minX; var height = maxY - minY;
同時,為了應對可能出現的假陰性,定義一個1.3的比例參數。
// Define scale factor to use to allow for false negatives around this region. var scale = 1.3; // Define scaled dimensions. var newWidth = width * scale; var newHeight = height * scale; // Caculate the offset to place new bounding box so scaled from center of current bounding box. var offsetX = (newWidth - width) / 2; var offsetY = (newHeight - height) / 2; var newXMin = minX - offsetX; var newYMin = minY - offsetY;
這個參數很重要,如果大了,背景的更新區域就會變小,影片的實時性也將受到影響;如果定義小了,那麼在人物快速移動時,會出現身體邊緣閃現的情況,這是一個工程上的取捨問題,感興趣的同學可以動手修改試一下。
而後,對除人體區域之外的區域(即背景部分)進行實時更新,當在定義的人體區域外檢測到人體(即人體出現了移動)時,即可對新的背景部分進行更新。
/ Now loop through update backgound understanding with new data // if not inside a bounding box. for (let x = 0; x < canvas.width; x++) { for (let y = 0; y < canvas.height; y++) { // If outside bounding box and we found a body, update background. if (foundBody && (x < newXMin || x > newXMin + newWidth) || ( y < newYMin || y > newYMin + newHeight)) { // Convert xy co-ords to array offset. let n = y * canvas.width + x; data[n * 4] = dataL[n * 4]; data[n * 4 + 1] = dataL[n * 4 + 1]; data[n * 4 + 2] = dataL[n * 4 + 2]; data[n * 4 + 3] = 255; } else if (!foundBody) { // No body found at all, update all pixels. let n = y * canvas.width + x; data[n * 4] = dataL[n * 4]; data[n * 4 + 1] = dataL[n * 4 + 1]; data[n * 4 + 2] = dataL[n * 4 + 2]; data[n * 4 + 3] = 255; } } } ctx.putImageData(imageData, 0, 0);
完整程式碼鏈接如下,感興趣的同學可以試試看?
https://codepen.io/jasonmayes/
TensorFlow.js能做的遠不止讓你「消失」
作者整個項目的核心是TensorFlow.js提供的身體分割模型,TensorFlow.js可以說是網站工程師使用機器學習模型的一個神器!
TensorFlow.js是一個使用JavaScript進行機器學習開發的庫,允許使用JavaScript進行機器學習模型的開發,並可以直接在瀏覽器或Node.js中使用機器學習模型。
而作者要讓鏡頭中人物「消失」,首先就要找到人體的位置區域,這裡使用的就是TensorFlow.js已經訓練好的身體分割模型。
比如上面這個項目所用的身體分割模型MobileNet,其調用十分簡單:
const net = await bodyPix.load({ architecture: 'MobileNetV1', outputStride: 16, multiplier: 0.75, quantBytes: 2 });
當然,除了MobileNet這種小而快但是準確率不是特別高的模型,也可以選擇ResNet這種大而慢但是準確率相對較高的模型。

並且除了身體分割模型,TensorFlow.js還提供影像分類、對象檢測、身體分割、句子編碼等多種現成的機器學習模型。當然,如果有需要,用戶也可以進行重新訓練自己的模型。

再或者,如果你想做一些有趣的事情放鬆一下,TensorFlow.js也絕對不會讓你失望。
知乎網友Henry,同時也是一位阿里的高級技術專家,就用TensorFlow.js做了一個完全獨立運行於瀏覽器環境下的AI程式,成功打爆了隱藏在Chrome中的彩蛋遊戲「暴龍酷跑」(T-Rex Runner)。
第一次,AI在嘗試3次後逐漸學會了如何控制暴龍避讓障礙物。

第二次,在引入遺傳演算法後,僅嘗試2次後AI即可學會躲避障礙物。

技術比創造力多一點點的15年老程式設計師
項目的作者的Jason Mayes在GitHub上的自我介紹是一位15年開發年齡的工程師,除了在GitHub留下足跡,他還給自己做了一個特別有意思的個人網站。
目前,Jason Mayes就職於Google「Creative Innovation」團隊,專門幫助Google的客戶開發訂製的Web解決方案,所以Jason對HTML、CSS和JavaScript十分熟練,因此在GitHub上的其他項目也都是用這幾種語言來實現。
比如他還寫過一個小程式,用來在網站上無縫排列自己的「貓片」,看著他為每一張照片配的旁白,資深「貓奴」無疑了。

在網站裡面,Jason形容自己是Web開發人員、程式設計師、技術顧問和分析師的混合型開發者,51%偏向技術,49%偏向創造。

的確,要成為一名合格的開發者,除了技術過硬,對這個世界的好奇心也是做出好項目的重要源泉。

「宅」家發獃,不如學嗨
手把手教你關聯數據的深度分析
配套TigerGragh部署與實戰解析
快掃碼到碗里來~