• <strike id="fdgpu"><input id="fdgpu"></input></strike>
    <label id="fdgpu"></label>
    <s id="fdgpu"><code id="fdgpu"></code></s>

  • <label id="fdgpu"></label>
  • <span id="fdgpu"><u id="fdgpu"></u></span>

    <s id="fdgpu"><sub id="fdgpu"></sub></s>
    您當(dāng)前的位置是:  首頁 > 新聞 > 文章精選 >
     首頁 > 新聞 > 文章精選 >

    教你如何結(jié)合WebRTC與TensorFlow實現(xiàn)圖像檢測(下篇)

    2018-01-10 10:49:31   作者:Chad Hart   來源:聲網(wǎng)Agora   評論:0  點擊:


      第3部分——瀏覽器端
      開始之前,請先在項目的根目錄位置創(chuàng)建一個static目錄。我們將從這里提供HTML和JavaScript。
      現(xiàn)在,我們首先使用WebRTC的getUserMedia抓取一個本地攝像頭Feed。從這里,我們需要將該Feed的快照發(fā)送到剛剛創(chuàng)建的對象檢測Web API,獲取結(jié)果,然后使用canvas實時地在視頻上顯示這些結(jié)果。
      HTML
      我們先創(chuàng)建local.html文件:
      此網(wǎng)頁的作用如下:
    • 使用WebRTC adapter.js代碼填充(polyfill)
    • 設(shè)置一些樣式,以便
    • 將各個元素一個個疊加起來
    • 將視頻放在底部,這樣我們就能使用canvas在它上面繪圖
    • 為我們的getUserMedia流創(chuàng)建一個視頻元素
    • 鏈接到一個調(diào)用getUserMedia的JavaScript文件
    • 鏈接到一個將與我們的對象檢測API交互并在我們的視頻上繪制方框的JavaScript文件
      獲取攝像頭流
      現(xiàn)在,在靜態(tài)目錄中創(chuàng)建一個local.js文件,并將下面的代碼添加到該文件中:
      在這里你會看到我們首先設(shè)置了一些約束條件。對于我自己的情況,我需要一段1280×720視頻,但要求范圍在640×480與1920×1080之間。然后,我們使用這些約束條件執(zhí)行g(shù)etUserMedia,并將所生成的流分配給我們在HTML中創(chuàng)建的視頻對象。
      對象檢測API的客戶端版本
      TensorFlow對象檢測API教程包含了可執(zhí)行以下操作的代碼:獲取現(xiàn)有圖像,將其發(fā)送給實際API進行“推斷”(對象檢測),然后為它所看到的對象顯示方框和類名。要想在瀏覽器中模擬這一功能,我們需要:
    • 抓取圖像——我們會創(chuàng)建一個canvas來完成這一步
    • 將這些圖像發(fā)送給API——為此,我們會將文件作為XMLHttpRequest中form-body的一部分進行傳遞
    • 再使用一個canvas將結(jié)果繪制在我們的實時流上
    • 要完成所有這些步驟,需要在靜態(tài)文件夾中創(chuàng)建一個objDetect.js文件。
      初始化和設(shè)置
      我們需要先定義一些參數(shù):
      你會注意到,我將其中一些參數(shù)作為data-元素添加到了自己的HTML代碼中。我最終是要在多個不同的項目中使用這段代碼,并且希望重用相同的代碼庫,而如此添加參數(shù)就可以輕松做到這一點。待具體使用這些參數(shù)時,我會一一解釋。
      設(shè)置視頻和canvas元素
      我們需要一個變量來表示我們的視頻元素,需要一些起始事件,還需要創(chuàng)建上面提到的2個canvas。
      drawCanvas用于顯示我們的方框和標(biāo)簽。imageCanvas用于向我們的對象檢測API上傳數(shù)據(jù)。我們需要向可見HTML添加drawCanvas,這樣我們就能在繪制對象框時看到它。接下來,需要跳轉(zhuǎn)到ObjDetect.js底部,逐函數(shù)向上編寫。
      啟動該程序
      1.觸發(fā)視頻事件
      我們來啟動該程序。首先要觸發(fā)一些視頻事件:
      先查找視頻的onplay事件和loadedmetadata事件——如果沒有視頻,圖像處理也就無從談起。我們需要用到元數(shù)據(jù)來設(shè)置我們的繪圖canvas尺寸,使其與下一部分中的視頻尺寸相符。
      2.啟動主對象檢測子例程
      雖然drawCanvas必須與視頻元素大小相同,但imageCanvas絕不會顯示出來,只會發(fā)送到我們的API。可以使用文件開頭的uploadWidth參數(shù)減小此大小,以幫助降低所需的帶寬量和服務(wù)器上的處理需求。需要注意的是,減小圖片可能會影響識別準(zhǔn)確度,特別是圖片縮減得過小的時候。
      至此我們還需要為drawCanvas設(shè)置一些樣式。我選擇的是cyan,但你可以任選顏色。只是要確保所選的顏色與視頻Feed對比明顯,從而提供很好的可見度。
      3.toBlob conversion
      設(shè)置好canvas大小后,我們需要確定如何發(fā)送圖像。一開始我采取的是較為復(fù)雜的方法,結(jié)果看到Fippo的grab()函數(shù)在最后一個KrankyGeek WebRTC事件處,所以我又改用了簡單的toBlob方法。待圖片轉(zhuǎn)換為blob(二進制大對象)后,我們就會將它發(fā)送到我們要創(chuàng)建的下一個函數(shù),即postFile。
      有一點需要注意——Edge似乎不支持HTMLCanvasElement.toBlob方法。好像可以改用此處推薦的polyfill或改用msToBlob,但這兩個我都還沒有機會試過。
      將圖像發(fā)送至對象檢測API
      我們的postFile接受圖像blob作為實參。要發(fā)送此數(shù)據(jù),我們需要使用XHR將其作為表單數(shù)據(jù)通過POST方法發(fā)布。不要忘了,我們的對象檢測API還接受一個可選的閾值,所以在這里我們也可以加入此閾值。為便于調(diào)整,同時避免操作此庫,你可以在我們在開頭設(shè)置的data-標(biāo)記中加入此參數(shù)及其他一些參數(shù)。
      我們設(shè)置好表單后,需要使用XHR來發(fā)送它并等待響應(yīng)。獲取到返回的對象后,我們就可以繪制它們(見下一個函數(shù))。這樣就大功告成了。由于我們想要持續(xù)不斷地執(zhí)行上述操作,因此我們需要在獲取到上一API調(diào)用返回的響應(yīng)后,立即繼續(xù)抓取新圖像并再次發(fā)送。
      繪制方框和類標(biāo)簽
      接下來我們需要使用一個函數(shù)來繪制對象API輸出,以便我們可以實際查看一下檢測到的是什么:
      由于我們希望每次都使用一個干凈的繪圖板來繪制矩形,我們首先要使用clearRect來清空canvas。然后,直接使用class_name對項目進行過濾,然后對剩余的每個項目執(zhí)行繪圖操作。
      在objects對象中傳遞的坐標(biāo)是以百分比為單位表示的圖像大小。要在canvas上使用它們,我們需要將它們轉(zhuǎn)換成以像素數(shù)表示的尺寸。我們還要檢查是否啟用了鏡像參數(shù)。如果已啟用,我們需要翻轉(zhuǎn)x軸,以便與視頻流翻轉(zhuǎn)后的鏡像視圖相匹配。最后,我們需要編寫對象class_name并繪制矩形。
      讓我們試一下吧!
      現(xiàn)在,打開你最喜歡的WebRTC瀏覽器,在地址欄中輸入網(wǎng)址。如果你是在同一臺計算機上運行,網(wǎng)址將為http://localhost:5000/local(如果設(shè)置了證書,則為https://localhost:5000/local)。
      關(guān)于優(yōu)化
      上述設(shè)置將通過服務(wù)器運行盡可能多的幀。除非為Tensorflow設(shè)置了GPU優(yōu)化,否則這會消耗大量的CPU資源(例如,我自己的情況是消耗了一整個核心),即便不作任何改動也是如此。更高效的做法是,限制調(diào)用該API的頻率,僅在視頻流中有新活動時才調(diào)用該API。為此,我在一個新的objDetectOnMotion.js文件中對objDetect.js做了一些修改。
      修改前后內(nèi)容大致相同,我只不過添加了2個新函數(shù)。首先,不再是每次都抓取圖像,而是使用一個新函數(shù)sendImageFromCanvas(),僅當(dāng)圖片在指定的幀率內(nèi)發(fā)生了變化時,該函數(shù)才發(fā)送圖片。幀率用一個新的updateInterval參數(shù)表示,限定了可以調(diào)用該API的最大間隔。為此,我們需要使用新的canvas和內(nèi)容。
      這段代碼很簡單:
      imageChangeThreshold是一個百分比,表示有改動的像素所占的百分比。我們獲得此百分比后將其傳遞給imageChange函數(shù),此函數(shù)返回True或False,表示是否超出了閾值。下面顯示的就是這個函數(shù):
      上面的這個函數(shù)其實是經(jīng)過大幅改進后的版本,之前的版本是我很久以前編寫的,用于在動作檢測嬰兒監(jiān)視器程序中檢測嬰兒動作。它首先測量每個像素的RGB顏色值。如果這些值與該像素的總體顏色值相比絕對差值超過10,則將該像素視為已改動。10只是隨意定的一個值,但在我的測試中似乎是很合適的值。如果有改動的像素數(shù)超出threshold,該函數(shù)就會返回True。
      對此稍微深入研究后,我發(fā)現(xiàn)其他一些算法通常轉(zhuǎn)換成灰度值,因為顏色并不能很好地反映動作。應(yīng)用高斯模糊也可以消除編碼差異。Fippo提出了一個很好的建議,即借鑒test.webrtc.org在檢測視頻活動時使用的結(jié)構(gòu)相似性算法(見此處此處)。后續(xù)還會分享更多技巧。
      適合任何視頻元素
      這段代碼實際上對任何
      不妨使用你自己的視頻試一下。只是提醒一下,如果你使用的是托管在另一臺服務(wù)器上的視頻,要注意CORS問題。
      一不小心寫成了長篇
      完成上面這一切耗費了很多時間,不過現(xiàn)在我希望開始著手有趣的部分了:嘗試不同的型號和訓(xùn)練我自己的分類器。已發(fā)布的對象檢測API是針對靜態(tài)圖像設(shè)計的。那么針對視頻和對象跟蹤進行了調(diào)整的模型又是什么樣的呢?很值得一試。
      此外,這里還有太多的優(yōu)化工作需要做。我在運行此服務(wù)時并沒有配備GPU,如果配備的話,性能會大為不同。如果幀的數(shù)量不多,支持1個客戶端需要大約1個核心,而我使用的是最快但準(zhǔn)確性最低的模型。在這方面有很大的性能提升空間。如果觀察此服務(wù)在GPU云端網(wǎng)絡(luò)中性能如何,想必也很有趣。
    【免責(zé)聲明】本文僅代表作者本人觀點,與CTI論壇無關(guān)。CTI論壇對文中陳述、觀點判斷保持中立,不對所包含內(nèi)容的準(zhǔn)確性、可靠性或完整性提供任何明示或暗示的保證。請讀者僅作參考,并請自行承擔(dān)全部責(zé)任。

    專題

    亚洲精品网站在线观看不卡无广告,国产a不卡片精品免费观看,欧美亚洲一区二区三区在线,国产一区二区三区日韩 沧州市| 河东区| 安仁县| 正阳县| 定安县| 马关县| 沛县| 佛坪县| 都昌县| 五河县| 松滋市| 河池市| 仙游县| 洪洞县| 辉南县| 高尔夫| 蒙自县| 偃师市| 阿坝| 临澧县| 湘西| 贵港市| 乌审旗| 始兴县| 桑日县| 桐庐县| 斗六市| 清水河县| 普安县| 平乡县| 航空| 无为县| 喀喇| 东光县| 巨鹿县| 星子县| 安化县| 丰县| 滁州市| 鄂州市| 峨山| http://444 http://444 http://444 http://444 http://444 http://444