视频会议玩消失?借助神器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就职于谷歌“Creative Innovation”团队,专门帮助谷歌的客户开发定制的Web解决方案,所以Jason对HTML、CSS和JavaScript十分熟练,因此在GitHub上的其他项目也都是用这几种语言来实现。
比如他还写过一个小程序,用来在网站上无缝排列自己的“猫片”,看着他为每一张照片配的旁白,资深“猫奴”无疑了。

在网站里面,Jason形容自己是Web开发人员、程序员、技术顾问和分析师的混合型开发者,51%偏向技术,49%偏向创造。

的确,要成为一名合格的开发者,除了技术过硬,对这个世界的好奇心也是做出好项目的重要源泉。

“宅”家发呆,不如学嗨
手把手教你关联数据的深度分析
配套TigerGragh部署与实战解析
快扫码到碗里来~