基於TensorFlow 、OpenCV 和 Docker 的實時視頻目標檢測

2020-12-08 雷鋒網

雷鋒網按:本文為雷鋒網字幕組編譯的技術博客,原標題 Real-time and video processing object detection using Tensorflow, OpenCV and Docker,作者為 Léo Beaucourt 。

翻譯 | 於志鵬  徐普     校對 | 陶玉龍     整理 | 孔令雙

在本文中,我將介紹如何在 Docker 容器中使用 Tensorflow Object-detection API 來執行實時(網絡攝像頭)和視頻的目標檢測。我使用 OpenCV 和 python3 的多任務處理庫 multiprocessing、多線程庫 multi-threading。

我會重點描述我在搭建過程中遇到的問題,以及我的解決方案 (有些還未解決)。完整的代碼在這裡 my Github:

https://github.com/lbeaucourt/Object-detection

使用Youtube視頻進行視頻處理測試

動機

我們從 Dat Tran 這篇文章開始挑戰實時目標檢測。我將使用 python 的 multiprocessing 庫,增加處理網絡攝像頭時的 FPS。為了進一步提高可移植性,我將項目集成到 Docker 容器中。不過處理進出容器的視頻流可能會有一點麻煩。

此外,在次項目我還添加了一個視頻後處理功能,同樣使用 multiprocessing 庫來減少處理時間(使用 Tensorflow 原始目標檢測 API 處理時間會非常長)。

實時和視頻目標識別都可以在我的個人筆記本電腦上以高性能運行,僅使用 8GB CPU。

Docker在數據科學中的應用

我不在這裡描述 Tensorflow 目標檢測 API 的實現,因為相關的文檔很多。我將展示數據科學家在日常工作中如何使用 Docker。注意,我會使用 Tensorflow 的經典 ssd_mobilenet_v2_coco 模型來提高性能。先將模型文件(.pb 文件)和相應的標籤映射文件複製到本地,後面可能會用到。


我認為使用 Docker 應是當今數據科學家的必備技能。在數據科學和機器學習領域,每周都會發布許多新的算法,工具和程序,直接在你的計算機目錄上安裝調試這些代碼、程序會讓系統變得凌亂不堪。為了防止這種情況,我使用 Docker 容器來創建我的數據科學工作區將程序部署在容器中。

你可以在我的代碼庫中找到這個項目的 Dockerfile。以下是我安裝配置 Tensorflow 目標檢測的方法(按照官方安裝指南):

# Install tensorFlow

RUN pip install -U tensorflow

# Install tensorflow models object detection

RUN git clone https://github.com/tensorflow/models /usr/local/lib/python3.5/dist-packages/tensorflow/models

RUN apt-get install -y protobuf-compiler python-pil python-lxml python-tk

#Set TF object detection available

ENV PYTHONPATH "$PYTHONPATH:/usr/local/lib/python3.5/dist-packages/tensorflow/models/research:/usr/local/lib/python3.5/dist-packages/tensorflow/models/research/slim"

RUN cd /usr/local/lib/python3.5/dist-packages/tensorflow/models/research && protoc object_detection/protos/*.proto --python_out=.

安裝 OpenCv 並編譯:

# Install OpenCV

RUN git clone https://github.com/opencv/opencv.git /usr/local/src/opencv

RUN cd /usr/local/src/opencv/ && mkdir build

RUN cd /usr/local/src/opencv/build && cmake -D CMAKE_INSTALL_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local/ .. && make -j4 && make install

編譯鏡像的時候有點長,之後就可以快速的調用

實時圖像目標檢測

我首先嘗試將目標檢測應用於我的網絡攝像頭。在 Dat Tran 的文章中有這部分的詳細描述。難點在於將網絡攝像頭流發送到 docker 容器並恢復輸出流以使用 X11 伺服器顯示它。

將視頻流發送到容器

Linux 系統可以在/ dev /目錄中找到攝像頭設備,並可以將其作為文件進行操作。通常筆記本電腦攝像頭是「0」設備。要將其數據流發送到 docker 容器,請在運行 docker 鏡像時使用 device 參數:

docker run --device=/dev/video0

對於 Mac 和 Windows 用戶,將網絡攝像頭流發送到容器的方式並不像 Linux 那樣簡單(儘管 Mac 基於 Unix)。我不在這裡過多介紹,可以查閱相關文檔,只提一下 Windows 用戶的解決方案是使用 Virtual Box 啟動 docker 容器。

在容器中恢復視頻流

解決這個問題我花了一段時間(然而並沒有完美解決)。我找到了一些使用 Docker 圖形界面的資料,here。特別是介紹了將容器連接到主機的 X 服務以顯示內容

你必須開啟 xhost,以便容器可以通過讀寫 X11 unix 套接字來正常的顯示內容。首先設置 X 伺服器主機的權限(有一定安全隱患)讓 docker 訪問它:

xhost +local:docker

在完成項目後,應當恢復默認設置

xhost -local:docker

然後創建兩個環境變量 XSOCK 和 XAUTH:

XSOCK=/tmp/.X11-unix

XAUTH=/tmp/.docker.xauth

第一個環境變量引用 X11 unix 套接字,第二個引用 X 驗證文件配置適當的權限:

xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -

最後,我們只需要更新我們的 docker run 命令。傳入我們的 DISPLAY 環境變量,為 X11 Unix 套接字增加一個卷,並為 X 身份驗證文件增加一個名為 XAUTHORITY 的環境變量,並讓該變量指向它:

docker run -it --rm --device=/dev/video0 -e DISPLAY=$DISPLAY -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH -e XAUTHORITY=$XAUTH

現在我們可以運行 docker 容器看看效果

目標檢測結果 (我是個害羞的人⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄)

儘管主機具有X服務配置,我仍不能完全刪除代碼中的bug。在OpenCV中 需要通過調用python 腳本(init-openCV.py)來進行初始化,即使用函數cv2.imshow  。用這種方法我得到了如下的錯誤消息:

The program 'frame' received an X Window System error.

然後,它可能調用主要python 腳本(my-object-detection.py) 並且將視頻流傳送到主機進行展示。我對使用第一個python 腳本去初始化X11系統的結果不是很滿意,但是目前我還沒有找到解決這個問題的方法。

後來補充:我最終(在偶然間)發現這個問題的解決方法,通過使用OpenCV (3.4.1) 這個穩定版本替代本地克隆的git庫。因此現在在主流python 腳本之前沒有必要調用 init openCV.py

視頻處理

為了能通過我的攝像頭實時運行目標檢測API ,我使用線程和多進程處理的python 庫。一個線程用於讀取攝像頭視頻流。視頻幀被放進一個隊列通過工作池去處理(Tensorflow目標檢測運行的地方)。

對於視頻處理而言,它不可能使用線程,因為所有的視頻幀都是在工作單元能將目標檢測應用在隊列第一幀之前被讀取。當輸入隊列滿後被讀取的視頻幀就會被丟失。使用大量工作單元和隊列可能可以解決這個問題(伴隨巨大的算力消耗)

簡單隊列的另外一個問題是,由於分析時間的不斷變化,視頻幀在輸出隊列中不是按照與輸入隊列相同的順序。

為了增加視頻處理功能,我刪掉了讀取幀率的線程。作為一個替代,我使用下面的代碼來讀取幀率。

while True:

  # Check input queue is not full

  if not input_q.full():

     # Read frame and store in input queue

     ret, frame = vs.read()

      if ret:            

        input_q.put((int(vs.get(cv2.CAP_PROP_POS_FRAMES)),frame))

如果輸入隊列沒滿,下一幀視頻從視頻流中讀取並且放進隊列中。否則,當視頻幀沒有從輸入隊列獲取時不會處理任何事情。

為了解決幀率順序的問題,我使用了如下這種優先隊列作為第二輸入隊列:

1. 視頻幀帶著對應的視頻幀編號被讀取並放入輸入隊列中(實際上是一個python 列表對象放入了序列)。

2. 然後,工作單元從輸入隊列中提取視頻幀,處理後將它們放入第一個輸出隊列(依然帶著它們相關的視頻幀編號)。

while True:

  frame = input_q.get()

frame_rgb = cv2.cvtColor(frame[1], cv2.COLOR_BGR2RGB)

  output_q.put((frame[0], detect_objects(frame_rgb, sess, detection_graph)))

3. 如果輸出隊列不為空,視頻幀帶著它們相應的優先視頻幀編號被抽取並放入優先隊列。優先隊列的大小被設置為其它隊列的三倍。

# Check output queue is not empty

if not output_q.empty():

  # Recover treated frame in output queue and feed priority queue

  output_pq.put(output_q.get())

4. 最後,如果輸出優先隊列不為空,則取出有最高優先編號的視頻幀(最小的優先編號)(這是標準的優先隊列工作)。如果優先級編號對應於預期的編號,視頻幀被加入輸出視頻流(並且根據需要寫入),其它的視頻幀則被放回優先隊列。

# Check output priority queue is not empty

  if not output_pq.empty():

    prior, output_frame = output_pq.get()

    if prior > countWriteFrame:

      output_pq.put((prior, output_frame))

    else: 

      countWriteFrame = countWriteFrame + 1    

      # Do something with your frame

為了停止這個過程,我檢查所有的隊列為空,並且所有的視頻幀已經從視頻流中抽取:

if((not ret) & input_q.empty() & 

    output_q.empty() & output_pq.empty()):

  break

總結

在這篇文章中,我展示了如何使用docker來實現Tensorflow的實時目標檢測項目。如上所述,docker是測試新數據科學工具最安全的方法,同時可以將解決方案打包給用戶。我也將如何採用來自Dat Tran 原始的python 腳本利用多進程去進行視頻處理展示給你。

謝謝你從頭到尾閱讀這篇文章。如上所述,這個項目有許多可以提高的地方。如果您有任何意見,請不要猶豫立刻告知我,我總是熱衷得到建議或評論。

原文連結:

https://towardsdatascience.com/real-time-and-video-processing-object-detection-using-tensorflow-opencv-and-docker-2be1694726e5

雷鋒網(公眾號:雷鋒網)字幕組編譯。

號外號外~

一個專注於

AI技術發展和AI工程師成長的求知求職社區

誕生啦!

歡迎大家訪問以下連結或者掃碼體驗

https://club.leiphone.com/page/home

雷鋒網原創文章,未經授權禁止轉載。詳情見轉載須知。

相關焦點

  • TensorFlow 攜手 NVIDIA,使用 TensorRT 優化 TensorFlow Serving...
    在這裡,我們運行 GPU Docker 圖像(點擊查看相關說明),從而藉助 GPU 創建並測試此模型:$ docker pull tensorflow/serving:latest-gpu$ docker run --rm --runtime=nvidia -p 8501:8501 --name tfserving_resnet \
  • TensorFlow 資源大全中文版
    循環神經網絡模型/工程圖片形態轉換 – 無監督圖片形態轉換的實現Show, Attend and Tell算法 -基於聚焦機制的自動圖像生成器Neural Style – Neural Style 算法的TensorFlow實現Pretty Tensor – Pretty Tensor提供了高級別的
  • 資源| TensorFlow版本號升至1.0,正式版即將到來
    發布地址官網:https://www.tensorflow.org/versions/r1.0/GitHub:https://github.com/tensorflow/tensorflow/releases主要特性和提升TensorFlow Debugger (tfdbg):命令行接口和 API增加新的 python 3 docker 鏡像使
  • 基於OpenCV和Tensorflow的深蹲檢測器
    OpenCV以及Tensorflow實現深蹲檢測在檢疫期間,我們的體育活動非常有限,這樣並不好。例如,檢測得到最大的輪廓只能包括人的身體,而不包括他的腳。但不管怎麼說,擁有一系列圖像對我很有幫助。通常情況下我們做深蹲運動都發生在同一地點,因此我們可以假設所有動作都在某個區域內進行並且該區域是穩定的。為此我們可以迭代構建邊界矩形,如果需要,可以以最大輪廓增加邊界矩形。
  • 深度解讀TensorFlow,了解它的最新發展!
    ++語言,研發人員可以將它與docker等容器集成使用。Tensorboard是tensorflow內置的一個可視化工具,它通過將tensorflow程序輸出的日誌文件的信息可視化,使得tensorflow程序的理解、調試和優化更加簡單高效。Tensorboard的可視化依賴於tensorflow程序運行輸出的日誌文件,因而tensorboard和tensorflow程序在不同的進程中運行。
  • 從R-CNN到YOLO,一文帶你了解目標檢測模型(附論文下載)
    它是將CNN用於對象檢測的起源,能夠基於豐富的特徵層次結構進行目標精確檢測和語義分割來源。如何確定這些邊界框的大小和位置呢?R-CNN網絡是這樣做的:在圖像中提出了多個邊框,並判斷其中的任何一個是否對應著一個具體對象。
  • TensorFlow極速入門
    一、前言目前,深度學習已經廣泛應用於各個領域,比如圖像識別,圖形定位與檢測,語音識別,機器翻譯等等,對於這個神奇的領域,很多童鞋想要一探究竟,這裡拋磚引玉的簡單介紹下最火的深度學習開源框架 tensorflow。
  • 【強化學習實戰】基於gym和tensorflow的強化學習算法實現
    1新智元推薦【新智元導讀】知乎專欄強化學習大講堂作者郭憲博士開講《強化學習從入門到進階》,我們為您節選了其中的第二節《基於gym和tensorflow的強化學習算法實現》,希望對您有所幫助。同時,由郭憲博士等擔任授課教師的深度強化學習國慶集訓營也將於 10 月 2 日— 6 日在北京舉辦。
  • TensorFlow 中文資源全集,學習路徑推薦
    入門教程,簡單的模型學習和運行。實戰項目,根據自己的需求進行開發。/GitHub:https://github.com/tensorflow安裝教程中文安裝教程Mac安裝:http://www.cnblogs.com/tensorflownews/p/7298646.htmlubuntu 16.04 安裝 tensorflow-gpu:http://www.tensorflownews.com/2017/09/02/tensorflow-gpu-install-ubuntu
  • 關於TensorFlow,你應該了解的9件事
    但如果你追求的是更大的目標,那就嗨起來吧~TensorFlow 被用於尋找新的行星,協助醫生檢查糖尿病性視網膜病變來預防患者失明,向當局報告非法砍伐行為來拯救森林。它是 AlphaGo 和 Google Cloud Vision 的基礎,也會是屬於你的。TensorFlow 是開源的,你可以免費下載並立即開始使用。
  • Agora新增支持Python:視頻通話中也可做圖像識別了
    Python 擁有很活躍的社區和豐富的第三方庫,Web 框架、爬蟲框架、數據分析框架、機器學習框架等,開發者無需重複造輪子,可以用 Python 進行 Web 編程、網絡編程,開發多媒體應用,進行數據分析,或實現圖像識別等應用。其中圖像識別是最熱門的應用場景之一,也是與實時音視頻契合度最高的應用場景之一。
  • 玩轉TensorFlow?你需要知道這30功能
    Tensor 的意思是張量,代表 N 維數組;Flow 的意思是流,代表基於數據流圖的計算。把 N 維數字從流圖的一端流動到另一端的過程,就是人工智慧神經網絡進行分析和處理的過程。地址是:tensorflow.org/tfx/?
  • 目標檢測必須要OpenCV?10行Python代碼也能實現,親測好用!
    無人超市、人臉識別、無人駕駛,眾多的使用場景及案例,使得【目標檢測】正成為計算機視覺最有前景的方向。聽起來似乎是個很難實現的技術,需要大量訓練數據和算法才能完成。事實上,本文作者開發了一個基於Python的函數庫,可以用十行代碼高效實現目標檢測。還不熟悉的讀者,我們先來看看,目標檢測到底是什麼,以及軟體開發人員面臨的挑戰。
  • 基於OpenCV來實現對圖像中目標對象檢測識別 以土地為例
    OpenCV是一款非常強大的圖像處理工具,對於從事圖像處理領域相關工作的人來說這個可以說是必不可少的一項工具,用起來也很方面,下嗎是一段簡單的介紹: OpenCV是一個基於BSD許可(開源)發行的跨平臺計算機視覺和機器學習軟體庫,可以運行在Linux、Windows、Android和Mac OS作業系統上。
  • TensorFlow極簡教程:創建、保存和恢復機器學習模型
    需求Python3 (https://www.python.org/)TensorFlow (https://www.tensorflow.org/)NumPy (http://www.numpy.org/)TensorFlow:保存/恢復和混合多重模型在第一個模型成功建立並訓練之後,你或許需要了解如何保存與恢復這些模型。
  • 基於RTX2060構建TensorFlow-gpu(keras)學習平臺
    開始菜單運行anaconda navigator檢查是否安裝了notebook(默認有安裝)三、安裝tensorflow/keras在激活的環境中安裝:1. 如果機器上有gpu,則安裝gpu版本,沒有GPU就安裝cpu版。
  • 使用OpenCV和Python構建自己的車輛檢測模型
    我們人類可以很容易地在一瞬間從複雜的場景中檢測和識別出物體。然而,將這種思維過程轉化為機器的思維,需要我們學習使用計算機視覺算法進行目標檢測。因此在本文中,我們將建立一個自動車輛檢測器和計數器模型。以下視頻是你可以期待的體驗:https://youtu.be/C_iZ2yivskE注意:還不懂深度學習和計算機視覺的新概念?
  • 步履不停:TensorFlow 2.4新功能一覽!
    ParameterServerStrategy        https://tensorflow.google.cn/api_docs/python/tf/distribute/experimental/ParameterServerStrategy參數伺服器訓練集群包含工作節點和參數伺服器。
  • TensorFlow 2.4來了:上線對分布式訓練和混合精度的新功能支持
    optimizer.minimize(loss, model.trainable_variables, tape=tape)這些更新的目標是讓 Model.fit 和自定義訓練循環與優化器細節更加不相關,從而讓使用者無需修改即可編寫出與任何優化器共同使用的訓練代碼。
  • 基於OpenCv 和 Python 的手指識別及追蹤
    翻譯 | 餘杭 Lamaric 校對 | 吳曉曼 審核 | 餘杭詳細代碼參考:https://github.com/amarlearning/opencv手指追蹤是許多計算機視覺應用的重要特徵。在該應用中,使用基於直方圖的方法將手與背景幀分離。