如果有个眼球追踪AI,加上人脸识别,或许就能在被老板盯上的瞬间,进入奋力工作模式。

8filters: 20,

5position: absolute;

3#train {

17$target.css( ‘left’, x + ‘px’);

图片 1

2const minX = positions[ 23][ 0] – 5;

18});

19model.add(tf.layers.flatten());

2const mouse = {

现在,在onStreaming() 的ctrack.starg() 后面,调用trackingLoop()
。每一帧里,它都会重新运行。

图片 2

10const targetWidth = $( ‘#target’).outerWidth();

5top: 50%;

8const height = maxY – minY;

25subset.x = tf.keep(image);

36}

1<div id= “target”></div>

8let currentPosition = ctrack.getCurrentPosition();

17validationData: [dataset.val.x, dataset.val.y],

27}));

24model.add(tf.layers.dense({

15// Move target there:

图片 3

9});

8returnbatchedImage.toFloat().div(tf.scalar( 127)).sub(tf.scalar( 1));

17}));

26activation: ‘tanh’,

15// Crop the eyes fromthe video andpaste them inthe eyes canvas:

18

5// Get the eyes rectangle anddraw it inred:

33});

图片 4

还有JS:

18$target.css( ‘top’, y + ‘px’);

绿色圈圈终于来了。AI判断你在看哪,它就出现在哪。

华为云•普惠AI,让开发充满AI!

3function createModel() {

11},

16const eyesCanvas = $( ‘#eyes’)[ 0];

浏览器每做一次渲染,我们就要在画布上画点什么了。画之前,要先把之前画过的内容擦掉。

第一步,要经过你 (用户)
同意,才能打开摄像头,渲染视频流,把画面显示在页面上。

鼻孔眼睛分不清?

35

模型代码长这样:

34

24// Create new tensors

然后,在页面上做个训练按钮吧:

6event.preventDefault();

1<canvas id= “overlay”width= “400”height= “300”></canvas>

10y: null,

1const ctrack = new clm.tracker();

6

9

33subset.y = tf.keep(oldY.concat(mousePos, 0));

然后,想让绿圈圈动起来,就要定期把眼睛图像传给神经网络。问它你在看哪,它就回答一个坐标:

7overlayCC.strokeStyle = ‘red’;

找到你的脸

自己训练传送门:

1const dataset = {

3<body>

4position: absolute;

https://cpury.github.io/learning-where-you-are-looking-at/

11inputShape: [$( ‘#eyes’).height(), $( ‘#eyes’).width(), 3],

2if(currentModel == null) {

比如,有时候会把鼻孔识别成眼睛。

2ctrack.init();

7// Normalize andreturnit:

14}

4position: absolute;

25}

在下试了一试。

8mouse.x = (event.clientX / $(window).width()) * 2- 1;

图片 5

就搭个最简单的CNN吧。

写好这几行,它应该已经能看出你的脸。不相信的话,就让它描出来

来自怪异君

16shuffle: true,

我来训练一把

这里,选23、28、24、26就够了,在每个方向上,往外扩大5个像素。

20}

13</style>

中间,加了一个dropout作为正则化器;还有,用flatten把2D数据降成1D。训练用的是Adam优化器。

28

11}

6handleMouseMove: function(event) {

果然,这次绿圈圈跑得自信了一些,左看右看它都驰骋 (比较) 如风。

8

26subset.y = tf.keep(mousePos);

Max也说,还有很多可以探索的空间。

4captureExample();

4

然后,矩形框应该足够覆盖重要面部信息了 (不离太远、不倒立) 。

7returnfalse;

4}

4const model = tf.sequential();

12

5top: 50%;

1<!doctype html>

4position: absolute;

14batchSize: batchSize,

11// factors to rescale the eyes rectangle before cropping:

20

9if(currentModel == null) {

7val: {

7< src= “main.js”></>

7kernelSize: 5,

2// Capture the current image inthe eyes canvas asa tensor.

5top: 0;

代码实现传送门:

3return;

39}

13}

接下来,要把矩形框提取出来。具体方法是,在第一张画布上把它描成红色,再复制到第二张画布上。

30const oldY = subset.y;

18const mousePos = tf.tensor1d([mouse.x, mouse.y]).expandDims( 0);

DIY全攻略 (上) :架子搭起来

230, 0, eyesCanvas.width, eyesCanvas.height

5

5const maxY = positions[ 26][ 1] + 5;

10activation: ‘relu’,

3const maxX = positions[ 28][ 0] + 5;

1function getEyesRectangle(positions) {

8</body>

8font-size: 24pt;

图片 6

20// Choose whether to add it to training ( 80%) orvalidation ( 20%)
set:

3

2<style>

8navigator.mediaDevices.getUserMedia({ video: true }).then(onStreaming);

2// Draw facial mask on overlay canvas:

9// Convert normalized position back to screen position:

至此,只要你按下空格,数据集里就会增加一个数据点了。

https://github.com/cpury/lookie-lookie

2const video = $( ‘#webcam’)[ 0];

圆栗子 编译整理

9}

眼球追踪模型很有意思,不过还是有一些可爱的缺陷。

教程原文传送门:

11if(currentPosition) {

这个模型叫Lookie
Lookie
,不用服务器,打开摄像头就可以在浏览器上训练,不出三分钟就能养成一只小AI。

9x: null,

训练开始之前,要先设置一个固定的epoch数,再把批尺寸设成变量(因为数据集很小)

34}

12}

1$( ‘body’).keyup(function(event) {

啊,老板的眼神飞过来了,还不快切回工作界面?

6left: 0;

2train: {

14

2 捕捉图像

4< src= “https://code.jquery.com/jquery-3.3.1.min.js"&gt;&lt;/&gt;

第一波,只要按20次空格,系统就提示,可以点击训练按钮了。

9});

8}

15epochs: 20,

9overlayCC.clearRect( 0, 0, 400, 300);

然后从main.js开始:

6left: 50%;

23// Two output values x andy

上文提到的clmtrackr.js人脸追踪器,这里就出场。

1// Track mouse movement:

20video,

间隔设的是100毫秒,不过也可以改的。

10</style>

1 追踪鼠标

6const image = getImage();

12ctrack.draw(overlay);

37subset.n += 1;

3if(batchSize < 4) {

16const $target = $( ‘#target’);

8overlayCC.strokeRect(eyesRect[ 0], eyesRect[ 1], eyesRect[ 2],
eyesRect[ 3]);

21

12const resizeFactorX = video.videoWidth / video.width;

9</html>

可它似乎有些犹豫。系统又提示:现在数据不太够,可能还没训练好,再取一些数据吧。

比如,必须整张脸都出现在画面里,才能识别眼睛的所在,捂住嘴也不行。

责任编辑:

1function getImage() {

9transition: all 0.1s ease;

所以,还是先检测人脸,再框出眼睛所在的部分。只把这个区域
(上图右一) 交给神经网络的话,任务就轻松了。

爱上你的代码,爱做 “改变世界”的行动派!

11border: 4px solid rgba( 0, 0, 0, 0.5);

7height: 40px;

4function onStreaming(stream) {

32subset.x = tf.keep(oldX.concat(image, 0));

收集数据的方式很简单,只要四处移动鼠标,眼睛跟着鼠标走,然后随时按下空格键,每按一次就采集一个数据点。

6const batchedImage = image.expandDims( 0);

https://cpury.github.io/lookie-lookie/

5// Add a batch dimension:

6batchSize = 64;

图片 7

4const image = tf.fromPixels($( ‘#eyes’)[ 0]);

21const subset = dataset[Math.random() > 0.2? ‘train’: ‘val’];

31

6}

摄像头拍到的画面就显示在屏幕左上角,脸上是绿色的轮廓,眼睛被一个红色方框框住。

这个网络里,要有一个卷积层,一个最大池化,还要有个密集层,带两个输出值
(坐标) 的那种。

5// Check ifa face isdetected, andifso, track it.

6border-radius: 50%;

3n: 0,

22eyesRect[ 2] * resizeFactorX, eyesRect[ 3] * resizeFactorY,

图片 8

然后,打开一个空的html文件,导入jQuery,
TensorFlow.js,clmtrackr.js,以及main.js。代码如下:

到这里,浏览器就该问你“要不要打开摄像头”了。

1ctrack.start(video);

1function moveTarget() {

12

6requestAnimationFrame(trackingLoop);

5} elseif(batchSize > 64) {

下面这个函数,会返回 (x,y)
坐标,以及矩形的长宽。给它输入的是clmtrackr里面的位置阵列 (Position
Array) :

4batchSize = 4;

7transform: translate( -50%, -50%);

以下是添加新数据点用的代码:

9}

21eyesRect[ 0] * resizeFactorX, eyesRect[ 1] * resizeFactorY,

7// Get the mouse position andnormalize it to [ -1, 1]

这样做还可以把坐标归一化 (转化到 [-1, 1] 的范围里) :

10},

13document.onmousemove = mouse.handleMouseMove;

相比之下,对于上下移动的目光,AI的反应似乎没有那么敏锐。大概是因为,电脑屏幕上下距离不够宽,眼球转动不充分吧。

5tf.tidy(function() {

这样,就有了跟视频尺寸一样的画布。CSS能保证画布和视频的位置完全吻合。

8</style>

从前,我们几乎无从躲避来自身后的目光,但现在不一定了。

35returnmodel;

29// Use ADAM optimizer withlearning rate of 0.0005andMSE loss

这样,便与检测模型的性能,以及确认它没有过拟合

10}

5y: null,

然后,在onStreaming()
里面,加下面这句话,就能让追踪器检测视频里的人脸了:

注意注意,虽然把所有数据做成一个大训练集也是可以的,但还是留一部分做验证集比较科学,比如20%。

15// Take the latest image fromthe eyes canvas andadd it to our dataset.

11}

4function trackingLoop() {

3if(event.keyCode == 32) {

5< src=
https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.12.0"&gt;&lt;/&gt;

3#target {

31optimizer: tf.train.adam( 0.0005),

大会将首次发布AI开发框架,从AI模型训练到AI模型部署的全套开发一站式完成!让AI开发触手可及!返回搜狐,查看更多

8n: 0,

15poolSize: [ 2, 2],

1<video id= “webcam”width= “400”height=
“300”autoplay></video>

8

19

3

13const y = (prediction.get( 0, 1) + 1) / 2* ($(window).height() –
targetHeight);

不过,在训练数据如此贫乏的前提下,神经网络也算是茁壮成长了。

1function fitModel() {

22setInterval(moveTarget, 100);

7}

22

13

11}

2let batchSize = Math.floor(dataset.train.n * 0.1);

5top: 0;

TensorFlow.js里面有一个和Keras很相似的API可以用。

9strides: 1,

19}

3returntf.tidy(function() {

9mouse.y = (event.clientY / $(window).height()) * 2- 1;

最后,把空格键关联进来:

来自慕尼黑的程序猿Max
Schumacher,就用TensorFlow.js做了一个模型,你看向屏幕的某一点,它就知道你在看的是哪一点了。

2

4position: absolute;

7const prediction = currentModel.predict(image);

21model.add(tf.layers.dropout( 0.2));

12const x = (prediction.get( 0, 0) + 1) / 2* ($(window).width() –
targetWidth);

18

这样,准备活动就做好了。下面正式开始。

2<style>

需要注意的是,收集数据的时候,脸不要离屏幕太远(也不要倒立🙃) 。

TensorFlow.js提供了一个助手函数,叫tf.fromPixels(),只要用它来储存第二张画布里走出的图像,然后归一化:

9});

5

眼睛截下来

1<button id= “train”>Train!</button>

代码长这样,写在ctrack.init() 下面:

7

1let currentModel;

想知道鼠标每时每刻都在什么位置,就给document.onmousemove加上一个EventListener。

4x: null,

先写绿圈圈:

6model.add(tf.layers.conv2d({

3#train {

19eyesCC.drawImage(

8width: 40px;

2<html>

32loss: ‘meanSquaredError’,

1$(document).ready(function() {

4background-color: lightgreen;

3x: 0,

10

原标题:三分钟训练眼球追踪术,AI就知道你在盯着哪个妹子 |
TensorFlow.js代码

这里要做的是,按下空格键之后的任务:从画布上捕捉图像,储存为张量。

30model.compile({

这一步,是要在眼睛周围画个矩形框

图片 9

德国少年选择了clmtrackr人脸检测模型,它的优点也是跑起来轻快。

导出视频流

眼球追踪,收集数据的方法其实有很多种。不过,让眼睛跟着鼠标走,是最简单的,随时按下空格都可以捕获一幅图像。

图片 10

25units: 2,

这个时候,刷新一下浏览器,你的脸上应该有一个绿色又诡异的轮廓了。

6< src= “clmtrackr.js”></>

23if(subset.x == null) {

9

训练模型

29const oldX = subset.x;

4const minY = positions[ 24][ 1] – 5;

14model.add(tf.layers.maxPooling2d({

10</style> 拉出来遛遛

3ctrack.draw(overlay);

2// On space key:

2const overlayCC = overlay.getContext( ‘2d’);

7

10// The video might internally have a different size, so we need these

2<style>

2<style>

19});

10currentModel = createModel();

7transform: translate( -50%, -50%);

16strides: [ 2, 2],

8font-size: 24pt;

训练好之后,屏幕上出现一个绿圈圈。这时候,我的眼睛看哪里,绿圈圈都应该跟着我走的。

6left: 50%;

替换trackingLoop()里面的if块:

7}

7const width = maxX – minX;

3#eyes {

10return[minX, minY, width, height];

13const resizeFactorY = video.videoHeight / video.height;

27} else{

那么,先把它下下来:

戏是有点多。不过眼球追踪这件事,只要有电脑的前置摄像头,再有个浏览器,真的可以做到。

10box-shadow: 0020px 10px white;

24);

图片 11

1const overlay = $( ‘#overlay’)[ 0];

36// Increase counter

13

14function captureExample() {

2<style>

7}

6},

总之,大功告成。

比如,算法还只能识别正面,脸稍微侧一点AI就会困惑。

1if(currentPosition) {

先写这行代码 (此处默认用的是最新版本的Chrome) :

作为一个不需要任何服务器就能训练的模型,如果要处理整幅整幅的视频截图,负担可能有些重。

1<button id= “train”>Train!</button>

DIY全攻略 (下) :训练与测试 收集数据

先在const video=…下面,初始化追踪器:

在<video>下面,写上这一串代码:

3#webcam, #overlay {

28// Concatenate it to existing tensors

17const image = getImage();

图片 12

cmltrackr很善良,除了画个轮廓之外,还有70个面部特征,我们可以选择自己需要的部分。

现在,应该看得到眼睛周围的红色矩形框了。

那好,再取个二三十张图,训练第二波。

5video.srcObject = stream;

13currentModel.fit(dataset.train.x, dataset.train.y, {

17const eyesCC = eyesCanvas.getContext( ‘2d’);

1<canvas id= “eyes”width= “50”height= “25”></canvas>

6right: 0;

12}));

这里需要一个绘图工具。用html里面的<canvas>标签,在视频上面重叠一张画布

4y: 0,

16tf.tidy(function() {

38});

11const targetHeight = $( ‘#target’).outerHeight();

8</style>

现在,再拿另外一张画布,来捕捉这个截下来的矩形。这张画布50 x
25
像素即可,只要把矩形框的尺寸调一下,就能放进去:

5

https://raw.githubusercontent.com/auduno/clmtrackr/dev/build/clmtrackr.js

14

12}

6const eyesRect = getEyesRectangle(currentPosition);

22

相关文章