網上有很多關于pos機開機一直初始化怎么解決,你需要訓練一只眼球追蹤AI嗎的知識,也有很多人為大家解答關于pos機開機一直初始化怎么解決的問題,今天pos機之家(www.www690aa.com)為大家整理了關于這方面的知識,讓我們一起來看下吧!
本文目錄一覽:
pos機開機一直初始化怎么解決
圓栗子 編譯整理
量子位 出品 | 公眾號 QbitAI
啊,老板的眼神飛過來了,還不快切回工作界面?
從前,我們幾乎無從躲避來自身后的目光,但現在不一定了。
如果有個眼球追蹤AI,加上人臉識別,或許就能在被老板盯上的瞬間,進入奮力工作模式。
戲是有點多。不過眼球追蹤這件事,只要有電腦的前置攝像頭,再有個瀏覽器,真的可以做到。
來自慕尼黑的程序猿Max Schumacher,就用TensorFlow.js做了一個模型,你看向屏幕的某一點,它就知道你在看的是哪一點了。
我來訓練一把這個模型叫Lookie Lookie,不用服務器,打開攝像頭就可以在瀏覽器上訓練,不出三分鐘就能養成一只小AI。
在下試了一試。
攝像頭拍到的畫面就顯示在屏幕左上角,臉上是綠色的輪廓,眼睛被一個紅色方框框住。
收集數據的方式很簡單,只要四處移動鼠標,眼睛跟著鼠標走,然后隨時按下空格鍵,每按一次就采集一個數據點。
第一波,只要按20次空格,系統就提示,可以點擊訓練按鈕了。
訓練好之后,屏幕上出現一個綠圈圈。這時候,我的眼睛看哪里,綠圈圈都應該跟著我走的。
可它似乎有些猶豫。系統又提示:現在數據不太夠,可能還沒訓練好,再取一些數據吧。
那好,再取個二三十張圖,訓練第二波。
果然,這次綠圈圈跑得自信了一些,左看右看它都馳騁 (比較) 如風。
相比之下,對于上下移動的目光,AI的反應似乎沒有那么敏銳。大概是因為,電腦屏幕上下距離不夠寬,眼球轉動不充分吧。
不過,在訓練數據如此貧乏的前提下,神經網絡也算是茁壯成長了。
需要注意的是,收集數據的時候,臉不要離屏幕太遠 (也不要倒立) 。
DIY全攻略 (上) :架子搭起來作為一個不需要任何服務器就能訓練的模型,如果要處理整幅整幅的視頻截圖,負擔可能有些重。
所以,還是先檢測人臉,再框出眼睛所在的部分。只把這個區域 (上圖右一) 交給神經網絡的話,任務就輕松了。
德國少年選擇了clmtrackr人臉檢測模型,它的優點也是跑起來輕快。
那么,先把它下下來:
https://raw.githubusercontent.com/auduno/clmtrackr/dev/build/clmtrackr.js
然后,打開一個空的html文件,導入jQuery, TensorFlow.js,clmtrackr.js,以及main.js。代碼如下:
1 <!doctype html>2 <html>3 <body>4 <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>5 <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.12.0"></script>6 <script src="clmtrackr.js"></script>7 <script src="main.js"></script>8 </body>9 </html>
這樣,準備活動就做好了。下面正式開始。
導出視頻流第一步,要經過你 (用戶) 的同意,才能打開攝像頭,渲染視頻流,把畫面顯示在頁面上。
先寫這行代碼 (此處默認用的是最新版本的Chrome) :
1 <video id="webcam" width="360px",height="auto" />
然后從main.js開始:
1 $(document).ready(function() {2 const video = $(\'#webcam\')[0];3 4 function onStreaming(stream) {5 video.srcObject = stream;6 }7 8 navigator.mediaDevices.getUserMedia({ video: true }).then(onStreaming);9 });
到這里,瀏覽器就該問你“要不要打開攝像頭”了。
找到你的臉上文提到的clmtrackr.js人臉追蹤器,這里就出場。
先在const video=…下面,初始化追蹤器:
1 const ctrack = new clm.tracker();2 ctrack.init();
然后,在onStreaming() 里面,加下面這句話,就能讓追蹤器檢測視頻里的人臉了:
1 ctrack.start(video);
寫好這幾行,它應該已經能看出你的臉。不相信的話,就讓它描出來。
這里需要一個繪圖工具。用html里面的<canvas>標簽,在視頻上面重疊一張畫布。
在<video>下面,寫上這一串代碼:
1 <canvas id="overlay" width="360px",height="auto" />
這樣,就有了跟視頻尺寸一樣的畫布。CSS能保證畫布和視頻的位置完全吻合。
瀏覽器每做一次渲染,我們就要在畫布上畫點什么了。畫之前,要先把之前畫過的內容擦掉。
代碼長這樣,寫在ctrack.init() 下面:
1 const overlay = $(\'#overlay\')[0]; 2 const overlayCC = overlay.getContext(\'2d\'); 3 4 function trackingLoop() { 5 // Check if a face is detected, and if so, track it. 6 requestAnimationFrame(trackingLoop); 7 8 let currentPosition = ctrack.getCurrentPosition(); 9 overlayCC.clearRect(0, 0, 400, 300);10 11 if (currentPosition) {12 ctrack.draw(overlay);13 }14 }
現在,在onStreaming() 的ctrack.starg() 后面,調用trackingLoop() 。每一幀里,它都會重新運行。
這個時候,刷新一下瀏覽器,你的臉上應該有一個綠色又詭異的輪廓了。
眼睛截下來這一步,是要在眼睛周圍畫個矩形框。
cmltrackr很善良,除了畫個輪廓之外,還有70個面部特征,我們可以選擇自己需要的部分。
這里,選23、28、24、26就夠了,在每個方向上,往外擴大5個像素。
然后,矩形框應該足夠覆蓋重要面部信息了 (不離太遠、不倒立) 。
現在,再拿另外一張畫布,來捕捉這個截下來的矩形。這張畫布50 x 25像素即可,只要把矩形框的尺寸調一下,就能放進去:
1 <canvas id="eyes" width="360px",height="auto" />
下面這個函數,會返回 (x,y) 坐標,以及矩形的長寬。給它輸入的是clmtrackr里面的位置陣列 (Position Array) :
1 function getEyesRectangle(positions) { 2 const minX = positions[23][0] - 5; 3 const maxX = positions[28][0] + 5; 4 const minY = positions[24][1] - 5; 5 const maxY = positions[26][1] + 5; 6 7 const width="360px",height="auto" />
接下來,要把矩形框提取出來。具體方法是,在第一張畫布上把它描成紅色,再復制到第二張畫布上。
替換trackingLoop() 里面的if塊:
1 if (currentPosition) { 2 // Draw facial mask on overlay canvas: 3 ctrack.draw(overlay); 4 5 // Get the eyes rectangle and draw it in red: 6 const eyesRect = getEyesRectangle(currentPosition); 7 overlayCC.strokeStyle = \'red\'; 8 overlayCC.strokeRect(eyesRect[0], eyesRect[1], eyesRect[2], eyesRect[3]); 910 // The video might internally have a different size, so we need these11 // factors to rescale the eyes rectangle before cropping:12 const resizeFactorX = video.videowidth="360px",height="auto" />
現在,應該看得到眼睛周圍的紅色矩形框了。
DIY全攻略 (下) :訓練與測試收集數據眼球追蹤,收集數據的方法其實有很多種。不過,讓眼睛跟著鼠標走,是最簡單的,隨時按下空格都可以捕獲一幅圖像。
1 追蹤鼠標
想知道鼠標每時每刻都在什么位置,就給document.onmousemove加上一個EventListener。
這樣做還可以把坐標歸一化 (轉化到 [-1, 1] 的范圍里) :
1 // Track mouse movement: 2 const mouse = { 3 x: 0, 4 y: 0, 5 6 handleMouseMove: function(event) { 7 // Get the mouse position and normalize it to [-1, 1] 8 mouse.x = (event.clientX / $(window).width="360px",height="auto" />
2 捕捉圖像
這里要做的是,按下空格鍵之后的任務:從畫布上捕捉圖像,儲存為張量。
TensorFlow.js提供了一個助手函數,叫tf.fromPixels() ,只要用它來儲存第二張畫布里走出的圖像,然后歸一化:
1 function getImage() { 2 // Capture the current image in the eyes canvas as a tensor. 3 return tf.tidy(function() { 4 const image = tf.fromPixels($(\'#eyes\')[0]); 5 // Add a batch dimension: 6 const batchedImage = image.expandDims(0); 7 // Normalize and return it: 8 return batchedImage.toFloat().div(tf.scalar(127)).sub(tf.scalar(1)); 9 });10 }
注意注意,雖然把所有數據做成一個大訓練集也是可以的,但還是留一部分做驗證集比較科學,比如20%。
這樣,便與檢測模型的性能,以及確認它沒有過擬合。
以下是添加新數據點用的代碼:
1 const dataset = { 2 train: { 3 n: 0, 4 x: null, 5 y: null, 6 }, 7 val: { 8 n: 0, 9 x: null,10 y: null,11 },12 }1314 function captureExample() {15 // Take the latest image from the eyes canvas and add it to our dataset.16 tf.tidy(function() {17 const image = getImage();18 const mousePos = tf.tensor1d([mouse.x, mouse.y]).expandDims(0);1920 // Choose whether to add it to training (80%) or validation (20%) set:21 const subset = dataset[Math.random() > 0.2 ? \'train\' : \'val\'];2223 if (subset.x == null) {24 // Create new tensors25 subset.x = tf.keep(image);26 subset.y = tf.keep(mousePos);27 } else {28 // Concatenate it to existing tensors29 const oldX = subset.x;30 const oldY = subset.y;3132 subset.x = tf.keep(oldX.concat(image, 0));33 subset.y = tf.keep(oldY.concat(mousePos, 0));34 }3536 // Increase counter37 subset.n += 1;38 });39 }
最后,把空格鍵關聯進來:
1 $(\'body\').keyup(function(event) {2 // On space key:3 if (event.keyCode == 32) {4 captureExample();56 event.preventDefault();7 return false;8 }9 });
至此,只要你按下空格,數據集里就會增加一個數據點了。
訓練模型就搭個最簡單的CNN吧。
TensorFlow.js里面有一個和Keras很相似的API可以用。
這個網絡里,要有一個卷積層,一個最大池化,還要有個密集層,帶兩個輸出值 (坐標) 的那種。
中間,加了一個dropout作為正則化器;還有,用flatten把2D數據降成1D。訓練用的是Adam優化器。
模型代碼長這樣:
1 let currentModel; 2 3 function createModel() { 4 const model = tf.sequential(); 5 6 model.add(tf.layers.conv2d({ 7 kernelSize: 5, 8 filters: 20, 9 strides: 1,10 activation: \'relu\',11 inputShape: [$(\'#eyes\').height(), $(\'#eyes\').width="360px",height="auto" />
訓練開始之前,要先設置一個固定的epoch數,再把批尺寸設成變量 (因為數據集很小) :
1 function fitModel() { 2 let batchSize = Math.floor(dataset.train.n * 0.1); 3 if (batchSize < 4) { 4 batchSize = 4; 5 } else if (batchSize > 64) { 6 batchSize = 64; 7 } 8 9 if (currentModel == null) {10 currentModel = createModel();11 }1213 currentModel.fit(dataset.train.x, dataset.train.y, {14 batchSize: batchSize,15 epochs: 20,16 shuffle: true,17 validationData: [dataset.val.x, dataset.val.y],18 });19 }
然后,在頁面上做個訓練按鈕吧:
1 <button id="train">Train!</button> 2 <style> 3 #train { 4 position: absolute; 5 top: 50%; 6 left: 50%; 7 transform: translate(-50%, -50%); 8 font-size: 24pt; 9 }10 </style>
還有JS:
1 <button id="train">Train!</button> 2 <style> 3 #train { 4 position: absolute; 5 top: 50%; 6 left: 50%; 7 transform: translate(-50%, -50%); 8 font-size: 24pt; 9 }10 </style>拉出來遛遛
綠色圈圈終于來了。AI判斷你在看哪,它就出現在哪。
先寫綠圈圈:
1 <div id="target"></div> 2 <style> 3 #target { 4 background-color: lightgreen; 5 position: absolute; 6 border-radius: 50%; 7 height: 40px; 8 width="360px",height="auto" />
然后,想讓綠圈圈動起來,就要定期把眼睛圖像傳給神經網絡。問它你在看哪,它就回答一個坐標:
1 function moveTarget() { 2 if (currentModel == null) { 3 return; 4 } 5 tf.tidy(function() { 6 const image = getImage(); 7 const prediction = currentModel.predict(image); 8 9 // Convert normalized position back to screen position:10 const targetwidth="360px",height="auto" />
間隔設的是100毫秒,不過也可以改的。
總之,大功告成。
鼻孔眼睛分不清?眼球追蹤模型很有意思,不過還是有一些可愛的缺陷。
比如,算法還只能識別正面,臉稍微側一點AI就會困惑。
比如,有時候會把鼻孔識別成眼睛。
比如,必須整張臉都出現在畫面里,才能識別眼睛的所在,捂住嘴也不行。
△ 來自怪異君
Max也說,還有很多可以探索的空間。
自己訓練傳送門:
https://cpury.github.io/lookie-lookie/
代碼實現傳送門:
https://github.com/cpury/lookie-lookie
教程原文傳送門:
https://cpury.github.io/learning-where-you-are-looking-at/
— 完 —
誠摯招聘
量子位正在招募編輯/記者,工作地點在北京中關村。期待有才氣、有熱情的同學加入我們!相關細節,請在量子位公眾號(QbitAI)對話界面,回復“招聘”兩個字。
量子位 QbitAI · 頭條號簽約作者
?\'?\' ? 追蹤AI技術和產品新動態
以上就是關于pos機開機一直初始化怎么解決,你需要訓練一只眼球追蹤AI嗎的知識,后面我們會繼續為大家整理關于pos機開機一直初始化怎么解決的知識,希望能夠幫助到大家!









